2013-07-30 31 views
0

我有一個播放文件的應用程序,每個文件都有它自己的運行時間,我只需將我的文件添加到我的Listview中,然後單擊播放按鈕。任務Parallel.ForEach在工作中報告

這是我的函數接受列表作爲輸入,這個名單包括我的所有文件,因爲我想要的選項來運行超過1個文件同時我可以控制的並行文件數:

public void doWork(IEnumerable<string> source, int parallelThreads) 
{ 
    _tokenSource = new CancellationTokenSource(); 
    var token = _tokenSource.Token; 
    Task.Factory.StartNew(() => 
    { 
     try 
     { 
      Parallel.ForEach(source, 
       new ParallelOptions 
       { 
        MaxDegreeOfParallelism = parallelThreads //limit number of parallel threads 
       }, 
       file => 
       { 
        if (token.IsCancellationRequested) 
         return; 
        //do work... 
       }); 
     } 
     catch (Exception) 
     { } 

    }, _tokenSource.Token).ContinueWith(
      t => 
      { 
       //finish... 
      } 
     , TaskScheduler.FromCurrentSynchronizationContext() //to ContinueWith (update UI) from UI thread 
     ); 
} 

時文件完成運行另一個文件開始播放(如果我選擇同時播放多個文件),並在這種情況下,我想更新我的用戶界面,特定的文件完成後,我怎麼能實時知道從任務具體文件完成和另一個文件開始?

+0

如何創建UI可以訂閱的事件?每次任務完成時只需觸發事件。只需確保在更新UI之前將'Invoke'調用到UI線程中。 – Pete

+0

我可以舉個例子嗎? (我是一名新開發人員) – user2214609

回答

0

我無法用編譯器測試這一點,而且我還沒有在一段時間內完成WinForms,所以這裏可能會有一些小的語法錯誤,但是這應該讓你朝着正確的方向前進:

... In your form code ... 

ClassNameHere myOb = new ClassNameHere(); 
myOb.FileComplete += new FileCompleteHandler(FileDone); 

... 

public void FileDone(object sender, EventArgs e) 
{ 
    if (InvokeRequired) 
    { 
     Invoke(new FileCompleteHandler(FileDone), new object[] { sender, e }); 
     return; 
    } 

    ... update UI here ... 
} 

然後,在你的類執行實際工作(你當然可以,叫任何你想要的類)。

public delegate void FileCompleteHandler(object sender, EventArgs e) 
public class ClassNameHere 
{ 

    protected virtual void OnFileComplete() 
    { 
     FileCompleteHandler handler = FileComplete; 
     if (handler != null) 
     { 
      handler(this, EventArgs.Empty); 
     } 
    } 

    public void doWork(IEnumerable<string> source, int parallelThreads) 
    { 
     _tokenSource = new CancellationTokenSource(); 
     var token = _tokenSource.Token; 
     Task.Factory.StartNew(() => 
     { 
      try 
      { 
       Parallel.ForEach(source, 
        new ParallelOptions 
        { 
         MaxDegreeOfParallelism = parallelThreads //limit number of parallel threads 
        }, 
        file => 
        { 
         if (token.IsCancellationRequested) 
          return; 
         //do work... 

         // This is where we tell the UI to update itself. 
         OnFileComplete(); 
        }); 
      } 
      catch (Exception) 
      { } 

     }, _tokenSource.Token).ContinueWith(
       t => 
       { 
        //finish... 
       } 
      , TaskScheduler.FromCurrentSynchronizationContext() //to ContinueWith (update UI) from UI thread 
      ); 
    } 

    public event FileCompleteHandler FileComplete; 
}