C#中的多线程和取消令牌

时间:2016-10-10 00:44:40

标签: c#

我是多线程的新手,浪费了几天没有运气调试这个程序。我正在尝试做概念验证,然后再继续实施并进行生产。

我有一个自定义对象列表。它们的属性是Task类型的T和int类型的Timeout。我试图在parrallel中多次执行任务,如果超时则终止任务。出于演示目的,我确实创建了两个简单的任务,他们做了简单的事情

  public class Program
{
    public static void Main(string[] args)
    {
        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        CancellationToken cancellationToken = cancellationTokenSource.Token;

        List<MyItem> myItems = new List<MyItem>();
        myItems.Add(createtask1(2000,1000,cancellationToken)); // this task should run for one second....result: should timeout
        myItems.Add(createtask2(2000,3000,cancellationToken));// this task should run for two second....result: should NOT timeout

        Parallel.ForEach(myItems,(item)=>{

           Task task = item.T;

            // start the task
            task.Start();

            Console.WriteLine("waiting for the task with timeout:{0} to finish", item.Timeout);
            try{
                bool hasNotTimedOut = task.Wait(item.Timeout);

                if (hasNotTimedOut)
                {
                    Console.WriteLine("Task with timeout: {0}, has not timed out", item.Timeout);
                }
                else
                {
                    Console.WriteLine("Task with timeout: {0}, has timed out", item.Timeout);
                        cancellationTokenSource.Cancel();
                        Console.WriteLine("Status of the task with timeout: {0} is {1}", item.Timeout,task.Status.ToString());

                }
            }
            catch (AggregateException ex)
            {
                if (ex.InnerException is OperationCanceledException)
                {
                    Console.WriteLine("Status of the task with timeout: {0} is {1}5", item.Timeout,task.Status.ToString());

                }
                else
                    Console.WriteLine(ex);
            }



            });

        //    Task.WaitAll(myItems.Select(item=>item.T).ToArray());        

        Console.WriteLine("End of Main");
    }

    private static MyItem createtask1(int delayTime, int timeout,CancellationToken cancellationToken)
    {
        MyItem toReturn = new MyItem();
        toReturn.Timeout = timeout;
        toReturn.T = new Task(()=>{
                              Console.WriteLine("Task1 is getting executed with DelayTime:{0}, timeout:{1}",delayTime,timeout);
                              Task.Delay(delayTime).Wait();
                              Console.WriteLine("Task1 finished executing with DelayTime:{0}, timeout:{1}",delayTime,timeout);
            cancellationToken.ThrowIfCancellationRequested();
                              },cancellationToken);


        return toReturn;                     

    }
    private static MyItem createtask2(int delayTime, int timeout,CancellationToken cancellationToken)
    {
        MyItem toReturn = new MyItem();
        toReturn.Timeout = timeout;
        toReturn.T = new Task(()=>{
                              Console.WriteLine("Task2 is getting executed with DelayTime:{0}, timeout:{1}",delayTime,timeout);
                              Task.Delay(delayTime).Wait();
                              Console.WriteLine("Task2 finished executing with DelayTime:{0}, timeout:{1}",delayTime,timeout);
            cancellationToken.ThrowIfCancellationRequested();
                              },cancellationToken);
        return toReturn;                     

    }
}

public class MyItem{
    public Task T{get;set;}
    public int Timeout{get;set;}
}

似乎它正在尝试取消上一个任务,但在我的情况下,第一个案例应该被取消。如果我不包含CancellationToken,我的代码可以正常工作,即它告诉我什么任务超时。

你能告诉我我做错了吗

0 个答案:

没有答案