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?
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.