也许我的大脑有点烧焦了,所以我错过了一些做以下事情的好方法……我希望能够通过在某个时间间隔运行的任务来启动计时器,并在每个时间间隔检查一些条件,看看它是否应该自动取消,最好的解决方案是什么?
最理想的情况是,我希望是这样的:
Task.Factory.StartNew(() =>
{
Timer.Do(TimeSpan.FromMilliSeconds(200),() => ShouldCancel(), ()=>
{
//DoStuff
});
});使用while/thread-sleep循环似乎并不是最优的。我想我可以定义和使用一个普通的计时器,但它看起来有点笨拙……
发布于 2011-03-23 00:48:07
下面的内容如何?我相信API可以稍微清理一下。
注意事项:
DoWork方法必须支持协作取消,这是任务并行库支持的唯一取消方法。
计时器必须在任务内部启动,否则任务可能会被创建和调度,但不会执行,计时器将是计时任务等待时间而不是执行时间。
如果您希望提供其他外部取消机制(其他令牌),则需要传入另一个上下文并链接它们。请参阅:CancellationTokenSource.CreateLinkedTokenSource
这只是近似值,因为System.Threading.Timer只有毫秒级的精度。它应该足够好,可以限制任务运行几秒钟。
public static class TimeLimitedTaskFactory
{
public static Task StartNew<T>
(Action<CancellationToken> action, int maxTime)
{
Task tsk = Task.Factory.StartNew(() =>
{
var cts = new CancellationTokenSource();
System.Threading.Timer timer = new System.Threading.Timer(o =>
{
cts.Cancel();
Console.WriteLine("Cancelled!");
}, null, maxTime, int.MaxValue);
action(cts.Token);
});
return tsk;
}
}
class Program
{
static void Main(string[] args)
{
int maxTime = 2000;
int maxWork = 10;
Task tsk = TimeLimitedTaskFactory
.StartNew<int>((ctx) => DoWork(ctx, maxWork), maxTime);
Console.WriteLine("Waiting on Task...");
tsk.Wait();
Console.WriteLine("Finished...");
Console.ReadKey();
}
static void DoWork(CancellationToken ctx, int workSize)
{
int i = 0;
while (!ctx.IsCancellationRequested && i < workSize)
{
Thread.Sleep(500);
Console.WriteLine(" Working on ", ++i);
}
}
}发布于 2012-06-12 19:06:13
您也可以使用RX library。
var timerTask = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(3));
timerTask.Subscribe(x =>
{
//Do stuff here
});发布于 2011-02-10 06:12:30
我想这就是你想要的:
var cancelToken = new CancellationTokenSource();
var tt = Task.Factory.StartNew(obj =>
{
var tk = (CancellationTokenSource) obj;
while (!tk.IsCancellationRequested)
{
if (condition)//your condition
{
//Do work
}
Thread.Sleep(1000);
}
}, cancelToken);https://stackoverflow.com/questions/4458618
复制相似问题