Reputation: 9461
What would I receive in result variable if completion source was cancelled?
async void SomeMethod()
{
.....
Run();
var result = await GetResult();
.....
}
Task<SomeResult> GetResult()
{
return myCompletionSource.Task;
}
TaskCompletionSource myCompletionSource;
void Run()
{
myCompletionSource= new TaskCompletionSource();
TriggerSomeLongLastingLogicWhichWillCallCallBackBelow();
}
void SomeCallback()
{
if (someCondition)
{
myCompletionSource.SetResult(<someResult>);
}
else
{
myCompletionSource.SetCancelled();
}
}
I'm not quite sure whether this approach is correct.
Upvotes: 2
Views: 2729
Reputation: 13495
What would I receive in result variable if completion source was cancelled?
You code will throw an OperationCancelledException
when awaiting a cancelled task. So the result variable will never be set.
You can handle the exception with a try/catch
block:
async Task SomeMethod()
{
try
{
.....
Run();
var result = await GetResult();
}
catch(OperationCancelledException)
{
// handle cancelled operation
}
}
Also, SomeMethod
should return a Task
as void
returning async
methods are usually only appropriate for event handlers as they must return void
. I blog about it briefly here.
In general, if you want an operation to be cancelable you pass in a CancellationToken
which the operation must check and pass on to other operations it kicks off. So you pass it all the way down the chain and into your callback.
You can also register a callback with the CancellationToken
that cancels the TaskCompletionSource
when the token is cancelled so you don't need to do it in your method.
void Run()
{
var cts = new CancellationTokenSource();
var myCompletionSource= new TaskCompletionSource();
cts.Token.Register(() => myCompletionSource.SetCancelled());
TriggerSomeLongLastingLogicWhichWillCallCallBackBelow(cts.Token);
}
void SomeCallback(CancellationToken token)
{
// do some work
....
token.ThrowIfCancellationRequested();
if (someCondition)
{
myCompletionSource.SetResult(<someResult>);
}
else
{
myCompletionSource.SetException(new Exception("error occcured"));
}
}
Upvotes: 4