Cancel task.delay without exception or use exception to control flow?

久未见 提交于 2019-12-05 04:56:11

If you want an immediate notification similar to what a cancellation gives you but without an exception you can simply use TaskCompletionSource.

TaskCompletionSource is how you create a promise task. You get an uncompleted task from the Task property and you complete it (or cancel) with SetResult. You can use it to actually pass on the result itself:

var tcs = new TaskCompletionSource<Events>();
eventProducer.RegisterListener(events => tcs.SetResult(events));

var result = await tcs.Task;
eventProducer.UnRegister(...);

This solution doesn't have any exceptions and doesn't use unnecessary polling


To answer your specific questions:

Am I overestimating the cost of throwing and catching an exception?

Probably. You need to test and prove it's really an issue.

And is there a way to cancel Task.Delay with a CancellationToken but without throwing a TaskCanceledException?

Yes. Add an empty continuation:

var delayTask = Task.Delay(1000, cancellationToken);
var continuationTask = delayTask.ContinueWith(task => { });
await continuationTask;

You can use _cancellationToken.WaitHandle.WaitOne(timeout in milliseconds); instead. It returns after the supplied timeout or immediately if the cancellation token is triggered, without throwing an exception.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!