【问题标题】:How to put a timeout on a method C#如何在方法 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 是您应该进行清理的地方。

标签: c# .net database multithreading netezza


【解决方案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 方法将继续在后台运行,但您的主线程可以继续。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多