2016-08-12 32 views
1

我有一個調用4個不同服務的Azure工作者角色,我希望能夠在它自己的線程中運行每個服務,並在完成時啓動另一個迭代。由於他們都需要不同的時間來跑步,所以在我完成一次任務之前,我不想等待所有人出現。我有這個這就要求他們都在序列使用While循環的多線程處理

public class WorkerRole : RoleEntryPoint 
{ 
    private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); 
    private readonly ManualResetEvent runCompleteEvent = new ManualResetEvent(false); 

    public override void Run() 
    { 
     Trace.TraceInformation("Polling.Worker is running"); 
     try 
     { 
      this.RunAsync(this.cancellationTokenSource.Token).Wait(); 
     } 
     finally 
     { 
      this.runCompleteEvent.Set(); 
     } 
    } 

    public override bool OnStart() 
    { 
     // Set the maximum number of concurrent connections 
     ServicePointManager.DefaultConnectionLimit = 12; 

     // For information on handling configuration changes 
     // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. 

     bool result = base.OnStart(); 

     Trace.TraceInformation("Polling.Worker has been started"); 

     return result; 
    } 

    public override void OnStop() 
    { 
     Trace.TraceInformation("Polling.Worker is stopping"); 

     this.cancellationTokenSource.Cancel(); 
     this.runCompleteEvent.WaitOne(); 

     base.OnStop(); 

     Trace.TraceInformation("Polling.Worker has stopped"); 
    } 

    private async Task RunAsync(CancellationToken cancellationToken) 
    { 
     while (!cancellationToken.IsCancellationRequested) 
     { 
      await Task.Run(() => 
      { 
       Debug.WriteLine("Starting Reddit Service"); 
       RedditService.GetObjects(); 
       Debug.WriteLine("Completed Reddit Service"); 
      }); 

      await Task.Run(() => 
      { 
       Debug.WriteLine("Starting TV Show Service"); 
       TVShowTicketService.GetObjects(); 
       Debug.WriteLine("Completed TV Show Service"); 
      }); 

      await Task.Run(() => 
      { 
       Debug.WriteLine("Starting Play By Play Service"); 
       PlayByPlayService.GetObjects(); 
       Debug.WriteLine("Completed Play By Play Service"); 
      }); 

      await Task.Run(() => 
      { 
       Debug.WriteLine("Starting Profile Service"); 
       ProfileService.Main(); 
       Debug.WriteLine("Completed Profile Service"); 
      }); 

      await Task.Delay(1000); 
     } 
    } 
} 

我知道,我在等待每一個線程,並且我希望能夠基本上都有一些,只是重複各功能一旦它是完整的,而機制,無需擔心其他線程。

+0

你的目標不明確。你爲什麼不用循環運行長期運行的任務中的每個服務?爲什麼角色必須管理每個服務的迭代,因爲你(似乎)想要做的就是反覆運行每個服務? _「有一些機制只是在完成每個功能時才重複」_--聽起來像是一個「while」循環,對於每項服務,每個服務都有一個服務。請解釋爲什麼這不適合你。 –

+0

我沒有關注,所以你提出一個任務,每個服務包含在一個單獨的循環中,或者每個服務的一個任務包含每個任務中的循環?也許一個小樣本會有幫助? –

+0

我已經添加了一個答案,我希望能夠解決所描述的問題。我意識到這可能不適用於你的情況(因爲假設它是你所做的,所以如果答案沒有幫助,請編輯你的問題以提供一個好的[mcve]和清楚的解釋爲什麼將'while'移動到每個任務中的簡單方法在您的情況下不起作用。 –

回答

1

如果我理解正確的話,你需要做的就是將您的while循環到每一個任務:

private async Task RunAsync(CancellationToken cancellationToken) 
{ 
    await Task.WhenAll(
     Task.Run(() => 
     { 
      while (!cancellationToken.IsCancellationRequested) 
      { 
       Debug.WriteLine("Starting Reddit Service"); 
       RedditService.GetObjects(); 
       Debug.WriteLine("Completed Reddit Service"); 
       await Task.Delay(1000); 
      } 
     }), 

     Task.Run(() => 
     { 
      while (!cancellationToken.IsCancellationRequested) 
      { 
       Debug.WriteLine("Starting TV Show Service"); 
       TVShowTicketService.GetObjects(); 
       Debug.WriteLine("Completed TV Show Service"); 
       await Task.Delay(1000); 
      } 
     }), 

     Task.Run(() => 
     { 
      while (!cancellationToken.IsCancellationRequested) 
      { 
       Debug.WriteLine("Starting Play By Play Service"); 
       PlayByPlayService.GetObjects(); 
       Debug.WriteLine("Completed Play By Play Service"); 
       await Task.Delay(1000); 
      } 
     }), 

     Task.Run(() => 
     { 
      while (!cancellationToken.IsCancellationRequested) 
      { 
       Debug.WriteLine("Starting Profile Service"); 
       ProfileService.Main(); 
       Debug.WriteLine("Completed Profile Service"); 
       await Task.Delay(1000); 
      } 
     })); 
} 

您可以通過一個輔助方法封裝重複的元素提高可讀性和可維護性:

private async Task RunAsync(CancellationToken cancellationToken) 
{ 
    await Task.WhenAll(
     RunServiceAsync(cancellationToken, RedditService.GetObjects, "Reddit"), 
     RunServiceAsync(cancellationToken, TVShowTicketService.GetObjects, "TV Show"), 
     RunServiceAsync(cancellationToken, PlayByPlayService.GetObjects, "Play By Play"), 
     RunServiceAsync(cancellationToken, ProfileService.Main, "Profile")); 
} 

Task RunServiceAsync(CancellationToken cancellationToken, Action service, string description) 
{ 
    return Task.Run(() => 
    { 
     while (!cancellationToken.IsCancellationRequested) 
     { 
      Debug.WriteLine("Starting " + description + " Service"); 
      service(); 
      Debug.WriteLine("Completed " + description + " Service"); 
      await Task.Delay(1000); 
     } 
    }); 
} 
+0

哇,正是我正在尋找。不太清楚爲什麼我認爲這會變得更加困難。謝謝! –