正确的方法来延迟任务的开始 [英] Correct way to delay the start of a Task
本文介绍了正确的方法来延迟任务的开始的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想安排一个任务开始以x ms,并能够取消它开始(或只是在任务开始)之前。
I want to schedule a task to start in x ms and be able to cancel it before it starts (or just at the beginning of the task).
第一次尝试将类似于
var _cancelationTokenSource = new CancellationTokenSource();
var token = _cancelationTokenSource.Token;
Task.Factory.StartNew(() =>
{
token.ThrowIfCancellationRequested();
Thread.Sleep(100);
token.ThrowIfCancellationRequested();
}).ContinueWith(t =>
{
token.ThrowIfCancellationRequested();
DoWork();
token.ThrowIfCancellationRequested();
}, token);
但我觉得应该有一个更好的办法,因为这将使用一个线程,而在睡觉,其间也可能被取消。
But I feel like there should be a better way, as this would use up a thread while in the sleep, during which it could be canceled.
我有什么其他选择?
推荐答案
如 Damien_The_Unbeliever提到,异步CTP包括 Task.Delay
。幸运的是,我们有反射器:
Like Damien_The_Unbeliever mentioned, the Async CTP includes Task.Delay
. Fortunately, we have Reflector:
public static class TaskEx
{
static readonly Task _sPreCompletedTask = GetCompletedTask();
static readonly Task _sPreCanceledTask = GetPreCanceledTask();
public static Task Delay(int dueTimeMs, CancellationToken cancellationToken)
{
if (dueTimeMs < -1)
throw new ArgumentOutOfRangeException("dueTimeMs", "Invalid due time");
if (cancellationToken.IsCancellationRequested)
return _sPreCanceledTask;
if (dueTimeMs == 0)
return _sPreCompletedTask;
var tcs = new TaskCompletionSource<object>();
var ctr = new CancellationTokenRegistration();
var timer = new Timer(delegate(object self)
{
ctr.Dispose();
((Timer)self).Dispose();
tcs.TrySetResult(null);
});
if (cancellationToken.CanBeCanceled)
ctr = cancellationToken.Register(delegate
{
timer.Dispose();
tcs.TrySetCanceled();
});
timer.Change(dueTimeMs, -1);
return tcs.Task;
}
private static Task GetPreCanceledTask()
{
var source = new TaskCompletionSource<object>();
source.TrySetCanceled();
return source.Task;
}
private static Task GetCompletedTask()
{
var source = new TaskCompletionSource<object>();
source.TrySetResult(null);
return source.Task;
}
}
这篇关于正确的方法来延迟任务的开始的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文