2015-11-01 28 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

相關問題