【问题标题】:Can not cancel a task after timeout period?超时后不能取消任务吗?
【发布时间】:2016-12-20 15:03:35
【问题描述】:

在我的MVC网站项目中,如果超时,我需要取消调用代码,我写了下面的代码,它在不超时时正确返回预期结果,但是当超时时,代码返回主线程但子任务还在运行(我检查了任务管理器,看到IIS Worker线程使用了很多硬件),我不知道它有什么问题。

    private static object GetCandidateOutput(MethodInfo mi, object o, string[][] input)
    {
        var cancellationToken = new CancellationTokenSource();
        var task = Task.Run(() => mi.Invoke(o, input), cancellationToken.Token);
        if (task.Wait(TimeSpan.FromSeconds(3)))
        {
            return task.Result;
        }
        else
        {
            cancellationToken.Cancel();
            throw new Exception("Timed out");
        }
    }

【问题讨论】:

  • cancellationToken.Cancel() 仅设置令牌的状态,以便如果有人检查它,他知道操作应该被取消。如果mi 中引用的方法正在执行,只要该方法不检查cancellationToken.IsCancellationRequested() 或调用cancellationToken.ThrowIfCancellationRequested()cancellationToken.Cancel() 就不起作用。对Cancel() 的调用本身不会“终止”任何任务或线程。
  • 调用代码来自另一个来源,我无法对其进行编辑以引发异常,在这种情况下如何等待和处理超时?

标签: .net timeout task


【解决方案1】:

我想通了,下面是工作代码:

var cts = new CancellationTokenSource();

var newTask = Task.Factory.StartNew(state =>
{
    var token = (CancellationToken)state;
    if (!token.IsCancellationRequested)
    {
        var invokeInput = new object[] { input };
        var output = mi.Invoke(o, invokeInput);
    }
}, cts.Token, cts.Token);


if (!newTask.Wait(timeout, cts.Token))
{
    cts.Cancel();
    throw new Exception("The operation has timed out.");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多