首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >匿名并行任务定时器?

匿名并行任务定时器?
EN

Stack Overflow用户
提问于 2010-12-16 16:09:43
回答 3查看 4.5K关注 0票数 2

也许我的大脑有点烧焦了,所以我错过了一些做以下事情的好方法……我希望能够通过在某个时间间隔运行的任务来启动计时器,并在每个时间间隔检查一些条件,看看它是否应该自动取消,最好的解决方案是什么?

最理想的情况是,我希望是这样的:

代码语言:javascript
复制
            Task.Factory.StartNew(() =>
            {
                 Timer.Do(TimeSpan.FromMilliSeconds(200),() => ShouldCancel(), ()=>
                 {
                     //DoStuff
                 });
            });

使用while/thread-sleep循环似乎并不是最优的。我想我可以定义和使用一个普通的计时器,但它看起来有点笨拙……

EN

回答 3

Stack Overflow用户

发布于 2011-03-23 00:48:07

下面的内容如何?我相信API可以稍微清理一下。

注意事项:

DoWork方法必须支持协作取消,这是任务并行库支持的唯一取消方法。

计时器必须在任务内部启动,否则任务可能会被创建和调度,但不会执行,计时器将是计时任务等待时间而不是执行时间。

如果您希望提供其他外部取消机制(其他令牌),则需要传入另一个上下文并链接它们。请参阅:CancellationTokenSource.CreateLinkedTokenSource

这只是近似值,因为System.Threading.Timer只有毫秒级的精度。它应该足够好,可以限制任务运行几秒钟。

代码语言:javascript
复制
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);
        }
    }
}
票数 3
EN

Stack Overflow用户

发布于 2012-06-12 19:06:13

您也可以使用RX library

代码语言:javascript
复制
var timerTask = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(3));
timerTask.Subscribe(x =>
                                    {
                                        //Do stuff here
                                    });
票数 1
EN

Stack Overflow用户

发布于 2011-02-10 06:12:30

我想这就是你想要的:

代码语言:javascript
复制
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);
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4458618

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档