如何在方法 C# 上设置超时

Posted

技术标签:

【中文标题】如何在方法 C# 上设置超时【英文标题】:How to put a timeout on a method C# 【发布时间】:2015-03-09 17:07:40 【问题描述】:

大家好,我有一个简短的问题要问大家。无论出于何种原因,一段代码不会定期返回,我还不能 100% 确定。为了解决这个问题,我想知道,使用下面的 Close() 方法,有没有办法让它超时?那么,如果它没有在 1 分钟左右的时间内完成,它会继续前进吗?

任何建议将不胜感激。谢谢,

如果有什么不同的话,写这篇文章的原作者指出他相信它挂在 close() 上并指出“也许太快了?” (该连接是与 Netezza 的 oledb 连接,整个应用程序是大量多线程的)。

无论如何,就目前而言,我只想让应用程序至少完成,而不是挂在那个异常捕获上。

下面是 Close();我相信这不会回来。

catch(Exception)
    Close(); //-- if we have an error, close everything down and then return the error
    throw;


public void Close() 
        if (null != Command) 
            Command.Cancel();
            Command.Dispose();
            Command = null;
        

        if (null != Connection) 
            if (Connection.State != System.Data.ConnectionState.Closed)
                Connection.Close();
            Connection.Dispose();
            Connection = null;
        

    

【问题讨论】:

请正确格式化您的代码。 您有一个名为 Command 的命令,它可以跨方法共享? DbCommand 有一个 TimeOut 属性,Finally 是您应该进行清理的地方。 【参考方案1】:

您真的是指命令超时,而不是方法超时?

基于 Close() 您正在共享命令和连接。 对于大量多线程的应用程序来说,这不是一个好的设计。 即使是轻度多线程应用程序,这也不是一个好的设计。

DbCommand 有一个超时属性

Using 语句将执行清理(包括关闭)

string connectionString = "";
// Wait for 5 second delay in the command
string queryString = "waitfor delay '00:00:05'";
using (OleDbConnection connection = new OleDbConnection(connectionString )) 
    connection.Open();
    SqlCommand command = new connection.CreateCommand();
    // Setting command timeout to 1 second
    command.CommandText = queryString;
    command.CommandTimeout = 1;
    try 
        command.ExecuteNonQuery();
    
    catch (DbException e) 
        Console.WriteLine("Got expected DbException due to command timeout ");
        Console.WriteLine(e);
    

【讨论】:

对不起,如果我解释得不好。我并不是说查询超时(我没有在上面添加,因为其余代码长达数百行),而是命令和连接无效挂起。【参考方案2】:

假设您使用的是 .NET 4.0 及更高版本,您可以使用 TPL 通过 System.Threading.Tasks.Task 对象执行此操作。您创建一个任务来异步运行一个方法,然后在该任务上等待您的超时持续时间,如果它过期 - 让主线程继续。

Task timeoutTask = new Task(Close); // create a Task around the Close method.
timeoutTask.Start(); // run asynchronously.
bool completedSuccessfully = timeoutTask.Wait(TimeSpan.FromMinutes(1));
if (completedSuccessfully)

    // Yay!

else

   logger.Write("Close command did not return in time. Continuing");

在本例中,Close 方法将继续在后台运行,但您的主线程可以继续。

【讨论】:

以上是关于如何在方法 C# 上设置超时的主要内容,如果未能解决你的问题,请参考以下文章

Selenium WebDriver - 如何使用 C# 设置页面加载超时

如何解决 C# IIS 托管的 WCF NET TCP 服务超时问题

如何在python的socket recv方法上设置超时?

如何:在检查不可用的网络共享时防止超时 - C#

c# 的web Service的超时时间设置问题

如何在 C# 中等待单个事件,带有超时和取消