2015-11-01 25 views
0

我正在尝试创建将使任何任务附加到父项的扩展方法。强制将任何任务附加到父项

扩展代码:

internal static class TaskHelpers 
{ 
    public static Task AttachToParrent(this Task task) 
    { 
     var tsc = new TaskCompletionSource<Task>(task.CreationOptions & TaskCreationOptions.AttachedToParent); 

     task.ContinueWith(_ => tsc.TrySetResult(task), TaskContinuationOptions.OnlyOnRanToCompletion); 

     task.ContinueWith(t => tsc.TrySetException(task.Exception ?? new AggregateException(new ApplicationException("Unknown"))), TaskContinuationOptions.OnlyOnFaulted); 

     task.ContinueWith(t => tsc.TrySetCanceled(), TaskContinuationOptions.OnlyOnCanceled); 

     return tsc.Task.Unwrap(); 
    } 
} 

测试代码:

static void Main(string[] args) 
    { 
     var cancellationTokenSource = new CancellationTokenSource(); 

     var task1 = Task.Factory.StartNew(() => 
     { 
      var task2 = Task.Factory.StartNew(() => 
      { 
       for (int i = 0; i < 5; i++) 
       { 


        if (!cancellationTokenSource.IsCancellationRequested) 
        { 
         Console.WriteLine(i); 

         Thread.Sleep(5000); 
        } 
        else 
        { 
         Console.WriteLine("Loop cancelled."); 

         break; 
        } 
       } 

      }, cancellationTokenSource.Token).AttachToParrent(); 

      var task3 = Task.Factory.StartNew(() => 
      { 
       for (int i = 0; i < 5; i++) 
       { 

        if (!cancellationTokenSource.IsCancellationRequested) 
        { 
         Console.WriteLine(i*10); 

         Thread.Sleep(5000); 
        } 
        else 
        { 
         Console.WriteLine("Loop cancelled."); 

         break; 
        } 
       } 

      }, cancellationTokenSource.Token).AttachToParrent(); 
     }, cancellationTokenSource.Token); 

     Console.WriteLine("Enter to cancel"); 

     Console.ReadKey(); 

     cancellationTokenSource.Cancel(); 

     Console.WriteLine("Waiting To Be Cancelled"); 

     task1.Wait(); 

     Console.WriteLine("Task Cancelled"); 

     Console.ReadKey(); 
    } 

父任务,而无需等待内部任务完成立即取消。我如何解决它,作为输入我得到一个任务,我在我的父分派器任务中执行。我想执行任何附加到父项的任务。

回答

1

发现问题的问题是

var tsc = new TaskCompletionSource<Task>(task.CreationOptions & TaskCreationOptions.AttachedToParent); 

tsc,CreationOptions保留为nooptions。

改为

var tsc = new TaskCompletionSource<Task>(TaskCreationOptions.AttachedToParent); 

现在一切正常。

+0

也许你打算使用'|'(按位或)?按位与('&')是一个逻辑与。在英语中,当你说“和”时,有时你的意思是“另外”,而在逻辑中(或者至少在这里),它总是意味着“交叉/重叠”。 – binki

2

调用Task.Factory.StartNew时(创建子任务,只有当)只需提供TaskCreationOptions.AttachedToParent

var task2 = Task.Factory.StartNew(..., cancellationTokenSource.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.Current); 

有关安装/拆卸任务的详细资料,请浏览MSDN

+0

问题是我不是创建任务的人。 – schizofreindly

相关问题