2013-07-30 29 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; 
}