首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >finally之前的return语句

finally之前的return语句
EN

Stack Overflow用户
提问于 2013-05-11 18:21:58
回答 4查看 954关注 0票数 5

我有一个c#程序,它充当客户端和许多客户端程序,这也是一个c# windows应用程序连接到这个c#服务器程序,从sqlite数据库读取数据。为了避免在连接多个客户端时出现锁定问题,我使用了下面的代码。

代码语言:javascript
复制
System.Threading.Monitor.Enter(Lock);

try                       
{                     
    filter.Execute();//get data from database
    Request.Clear();
    return filter.XML;//create xml and return to client
}
finally
{
    System.Threading.Monitor.Exit(Lock);
}

服务器挂起了几次,需要重新启动服务器程序。在finally之前执行return语句是一种好的做法吗?

尊敬sangeetha

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-05-11 18:27:10

来自MSDN

通过使用finally块,可以清理在try块中分配的任何资源,并且即使try块中发生异常,也可以运行代码。通常,当控制离开try语句时,finally块的语句就会运行。控制权的转移可能是正常执行、break、continue、goto或return语句执行的结果,也可能是try语句之外传播异常的结果。

在已处理的异常中,可以保证运行关联的finally块。但是,如果异常未处理,则finally块的执行取决于异常展开操作的触发方式。而这又取决于您的计算机的设置方式。有关更多信息,请参见CLR中的未处理异常处理。

票数 4
EN

Stack Overflow用户

发布于 2013-05-11 18:25:33

是的,这就是finally语句的用途。它将在return之后执行,即使发生异常

EDIT:这段简单的代码将向您展示,catch块并不是执行finally块所必需的

代码语言:javascript
复制
public Form1()
{
    InitializeComponent();
    check();
}

private string check()
{
    try
    {
        return String.Empty;
    }
    finally
    {
        MessageBox.Show("finally");
    }
}
票数 2
EN

Stack Overflow用户

发布于 2013-05-11 19:08:17

因为没有catch块,所以不能保证最终会被执行。来自MSDN - try-finally (C# Reference)"Locks and exceptions do not mix" (Eric Lippert)

在已处理的异常中,关联的finally块将保证运行。但是,如果异常未处理,则finally块的执行取决于异常展开操作的触发方式。而这又取决于您的计算机的设置方式。

从随后提到的链接(Unhandled Exception Processing In The CLR)开始,有各种考虑因素,这可能意味着您最终会得到一个终止的线程。老实说,我不知道这是否会给你留下一个锁在锁对象上。

如果您想要确保:

  • 您释放锁;但
  • 您不希望在此级别处理异常,而是希望由更高级别的异常处理程序

处理它

然后执行以下操作:

代码语言:javascript
复制
TheXmlType xml = null;
Monitor.Enter(Lock);
bool inLock = true;
try {
  ...
  xml = filter.Xml; // put this here in case it throws an exception
  inLock = false; // set this here in case monitor.exit is to 
    // throw an exception so we don't do the same all over again in the catch block
  Monitor.Exit(Lock);
  return xml; // this is fine here, but i would normally put it outside my try
}
catch (Exception) {
  if (inLock) Monitor.Exit(Lock);
  throw;
}

但是,请注意:不要使用catch (Exception)来隐藏异常,只有当您重新抛出异常时才可以。人们还建议你只使用一条return语句,通常这会在你的try块之外。

编辑:

使用测试程序进行确认,并来自MSDN - Exceptions in Managed Threads

从.NET Framework2.0版开始,公共语言运行库允许线程中大多数未处理的异常自然处理。在大多数情况下,这意味着未处理的异常会导致应用程序终止。

因此,如果您不处理您的异常,您的应用程序将崩溃(并且您不必担心锁)。如果你确实处理了它,那么你的原始代码就会执行它的finally块,你就没问题了。

EDIT 2:测试代码更新,因为它没有正确地说明非触发最终:

代码语言:javascript
复制
class Program
{ 
    static void Main(string[] args) {
        Program p =new Program();
        p.Start();
        Console.WriteLine("done, press enter to finish");
        Console.ReadLine();
    }

    private readonly object SyncRoot = new object();
    ManualResetEvent mre = new ManualResetEvent(false);

    private void Start() {
        /*
         * The application will run the thread, which throws an exception
         * While Windows kicks in to deal with it and terminate the app, we still get 
         * a couple of "Failed to lock" messages
         * */

        Thread t1 = new Thread(SetLockAndTerminate);
        t1.Start();
        mre.WaitOne();
        for (int i = 0; i < 10; i++) {
            if (!Monitor.TryEnter(this.SyncRoot, 1000)) {
                Console.WriteLine("Failed to lock");
            }
            else {
                Console.WriteLine("lock succeeded");
                return;
            }
        }
        Console.WriteLine("FINALLY NOT CALLED");
    }
    public int CauseAnOverflow(int i)
    {
        return CauseAnOverflow(i + 1);
    }
    public void SetLockAndTerminate() {
        Monitor.Enter(this.SyncRoot);
        Console.WriteLine("Entered");
        try {
            mre.Set();
            CauseAnOverflow(1); // Cause a stack overflow, prevents finally firing
        }
        finally {
            Console.WriteLine("Exiting");
            Monitor.Exit(this.SyncRoot);
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16496088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档