none
怎样实时手动管理多个Task的执行问题 RRS feed

  • 问题

  • 大家好,有个问题一直困扰我,我们的App在进入页面后需要去连续获取网络多个业务资源,耗时较长,离开页面时我想结束掉这些所有未执行完毕的Task,看了下目前的做法是用CancellationTokenSource 控制,但是这个方法有弊端,需要传参数,往往在实际项目中很多逻辑都是在业务层,这样UI层调用Control,control再调用Biz,如果要用CancellationTokenSource我得在每层相应的方法上加这个参数,这样就严重破坏了程序集业务的独立性,因为这个参数从业务角度讲没有任何意义,请问大家还有没有其他的方法,能控制这些Task呢?



    • 已编辑 eWalk 2013年10月15日 3:32
    2013年10月15日 3:31

答案

全部回复

  • 您好,你可以把相关的所有类的CancelToken进行一个串联,如果是一批任务,一批统一取消,看我示例代码:

    using System;
    using System.Threading;
    using System.Threading.Tasks;
     
    namespace MultiCore
    {
        class MainTest
        {
            static void Main(string[] args)
            {
                Random r = new Random();
     
                CancellationToken ct1=new CancellationTokenSource().Token;
                CancellationToken ct2=new CancellationTokenSource().Token;
                CancellationToken ct3=new CancellationTokenSource().Token;
     
                Task t = new Task(() =>
                {
                    Console.WriteLine("Task 1 Started...");
                    for (int i = 1i < 6i++)
                    {
                        ct1.ThrowIfCancellationRequested();
                        Thread.Sleep(r.Next(10006000));
                    }
                }, ct1);
     
                Task t2 = new Task(() =>
                {
                    Console.WriteLine("Task 2 Started...");
                    for (int i = 1i < 6i++)
                    {
                        ct3.ThrowIfCancellationRequested();
                        Thread.Sleep(r.Next(10006000));
                    }
                },ct2);
                Task t3 = new Task(() =>
                {
                    Console.WriteLine("Task 3 Started...");
                    for (int i = 1i < 6i++)
                    {
                        ct3.ThrowIfCancellationRequested();
                        Thread.Sleep(r.Next(10006000));
                    }
                },ct3);
     
                t.Start();
                t2.Start();
                t3.Start();
               
                //Register for all cancellistTokens
                CancellationTokenSource cst = CancellationTokenSource.CreateLinkedTokenSource(ct1ct2ct3);
                cst.Token.Register(() => 
                {
                    Console.WriteLine("Thread is cancelled.");
                });
                //After a random time, all the threads should stop immediately!
                cst.CancelAfter(r.Next(20005000));
     
                Task.WaitAll(tt2t3);
            }
        }
    }

    Click For donating:Free Rice For the poor
    For spamming-sender issues, you can either report it at Microsoft Spamming Issue, or just find "Report Spam Here+Number" at Forum Issue;You can also find "Verify Your Account+Number" at "Forum Issue", where you can submit to be confirmed to paste links or images.
    For more things to talk about? StackOverFlow is your choice.

    2013年10月15日 4:40
  • 非常感谢您的回答,其实我的困惑是更侧重于另外一个层面的,我的业务层是一个单独的dll,里面有很多复杂的业务接口,在这些接口里有很多执行较长时间的任务,我的意思是UI层怎么通知业务层取消当前正在执行的任务,如果我用CancellationTokenSource的话,我必须得在UI层定义一个该类型的实例,然后一步步的将其传参数到业务层,这样无形多了一个和业务无关的参数我觉得很不好!我的意思是不想传参CancellationTokenSource这个参数到业务层接口以保证业务逻辑的纯正,谢谢!
    2013年10月15日 6:29
  • 那恐怕你还得定义个中间层,使用中间层隔离业务层以及UI进行控制。

    Click For donating:Free Rice For the poor
    For spamming-sender issues, you can either report it at Microsoft Spamming Issue, or just find "Report Spam Here+Number" at Forum Issue;You can also find "Verify Your Account+Number" at "Forum Issue", where you can submit to be confirmed to paste links or images.
    For more things to talk about? StackOverFlow is your choice.

    2013年10月15日 6:52