【问题标题】:How to cancel suspended method by timeout?如何通过超时取消暂停方法?
【发布时间】:2015-06-18 08:22:23
【问题描述】:

我知道如何取消超时执行的方法。我的意思是Task-Wait-Timeout-CancellationToken 把戏。 IE。方法包装在任务中。这种技术效果很好。例如:

private void TestConnectMethod()
{
    int QueryTimeOut = 1000; //in ms

    _txtError.Visibility = Visibility.Hidden;

    var cancellationTokenSource = new CancellationTokenSource();
    var token = cancellationTokenSource.Token;

    var task = Task.Factory.StartNew(() =>
    {
        while (true)
        {
            if (token.IsCancellationRequested)
               token.ThrowIfCancellationRequested();

            Debug.WriteLine("Iteration" + DateTime.Now);
        }

    }, token).ContinueWith(t =>
    {

    });

    var wres = task.Wait(QueryTimeOut);

    if (!wres)
    {
        cancellationTokenSource.Cancel();
        _txtError.Text = "Timeout!";
    }
    else
    {
        _txtError.Text = "All is ОК";
    }
}

任务将被成功取消。但是如果 Task 看起来像这样:

var task = Task.Factory.StartNew(() =>
    {
        // This is a server method that can be suspended
        ArchiveServiceClient.Instance.Authenticate()
    }, token).ContinueWith(t =>
    {

    });

ArchiveServiceClient.Instance.Authenticate() 方法可以在服务器没有响应时暂停应用程序。现在,我不能写了

if (token.IsCancellationRequested)
    token.ThrowIfCancellationRequested();

因为这些字符串将毫无用处。如何停止 Task 使用挂起方法执行?有可能吗?

【问题讨论】:

  • 1) 如果您调用的方法不支持超时/取消,您无法优雅地停止它。 2)但是为什么这会暂停应用程序?它不应该简单地阻塞它正在运行的线程吗? 3)你为什么用if (token.IsCancellationRequested) token.ThrowIfCancellationRequested();而不是token.ThrowIfCancellationRequested();
  • @CodesInChaos, 2) - 你说得对,它只会阻塞线程,但对我来说这也是不可接受的。 3)这里没关系,两种方法的工作方式相同。

标签: c# task cancellation


【解决方案1】:

一般来说,您无法取消执行任何代码。

您首先发布的示例假定该代码支持优雅取消模式。当然,并非每个方法/类/库都如此,ArchiveServiceClient.Instance.Authenticate 演示了这一点。

Tread.Abort 有一些技巧,但你应该避免它们,因为它们比有用更有害,而且你不能用这种方式取消非托管代码。

从 .NET 应用程序中取消某些内容的唯一可靠方法是将该内容放在单独的进程中,并在超时时终止该进程。当然,与优雅取消相比,这需要更复杂的方法。

【讨论】:

  • 谢谢,我怎样才能让任务的线程中止它? (只是为了好玩)。我在任务对象中看不到任何 fit 属性。
  • 在任务正文中使用Thread.CurrentThread。我不建议中止线程池线程(默认任务将使用线程池)。
  • @Dennis,不幸的是我需要从这里中止任务线程if (!wres) { }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 2016-03-26
相关资源
最近更新 更多