How to cancel suspended method by timeout?

145 views Asked by At

I know how I can cancel method executing by timeout. I mean Task-Wait-Timeout-CancellationToken trick. I.e. method is wrapped in Task. This technique works fine. For example:

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 will be cancelled succesfully. But what if Task look like this:

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

    });

ArchiveServiceClient.Instance.Authenticate() method can suspend application if server doesn't respond. Now, I cannot write

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

because these strings will be useless. How can I stop Task executing with suspended method? Is it possible?

1

There are 1 answers

3
Dennis On

In general, you can't cancel execution of any code.

The sample you've posted first, assumes, that code supports graceful cancellation pattern. Of course, this isn't true for every method/class/library, what ArchiveServiceClient.Instance.Authenticate demonstrates.

(There are some tricks with Tread.Abort, but you should avoid them, because they are more harmful, than useful, and you can't cancel unmanaged code this way).

The only reliable way to cancel something from .NET application is to put that something in separate process, and kill the process on timeout. Of course, this requires more complex approach, comparing to graceful cancellation.