如何通过超时取消暂停的方法?

时间:2015-06-18 08:22:23

标签: c# task cancellation

我知道如何取消超时执行方法。我的意思是Task-Wait-Timeout-CancellationToken技巧。即方法包含在Task中。这种技术很好用。例如:

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 个答案:

答案 0 :(得分:1)

通常,您无法取消任何代码的执行。

您首先发布的示例假设该代码支持优雅的取消模式。当然,对于每个方法/类/库来说都不是这样,ArchiveServiceClient.Instance.Authenticate演示了什么。

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

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