2015-04-07 39 views
-1

中的事件我有一个生产者 - 消费者乘法任务Class。 我有一个方法:C#raise Task.WhenAll()

private async Task Consume(CancellationToken cancellationToken){..} 

存在起动方法:

public void Run() 
    { 
     var workerCount = Session.GetParameters().GetThreadCount(); 
     _workers = new List<Task>(workerCount); 
     for (var i = 0; i < workerCount; i++) 
      _workers.Add(Consume(StopCancellationTokenSource.Token)); 
     Task.WhenAll(_workers).ContinueWith(_ => DoneEvent); 
    } 

的问题是,DoneEvent被解雇,但用户事件处理从未得到执行。 我成功运行事件处理程序的唯一方法是在此创建Run方法async并在Task.WhenAll(..)之前添加等待。但后来又提出了另一个问题在方法Consume()我有一个ManualResetEvent PauseBlock。当它重置时,主线程也会等待。

Thnx提前。

编辑: 我设法把事情做对(2天内) 我已经改变了一点点Run方法:

public async void Run() 
    { 
     var workerCount = Session.GetParameters().GetThreadCount(); 
     _workers = new List<Task>(workerCount); 
     for (var i = 0; i < workerCount; i++) 
      _workers.Add(Task.Run(()=> Consume(StopCancellationTokenSource.Token))); 
     await Task.WhenAll(_workers); 
     DoneEvent(); 
    } 

现在它工作正常。 仅供参考消费者方法:

private async Task Consume(CancellationToken cancellationToken) 
    { 
     try 
     { 
      await Task.Delay(5000, cancellationToken); 
      IEngGroup engGroup; 
      while (Groups.TryDequeue(out engGroup)) 
      { 
       cancellationToken.ThrowIfCancellationRequested(); 

       if (!engGroup.IsEnabled || engGroup.Result.Status == ItemRunningStatus.Successful) continue; 

       if (engGroup.IsBreak) Pause(); 
       //if paused wait 
       PauseBlock.WaitOne(); 
       //if stoped throw 
       cancellationToken.ThrowIfCancellationRequested(); 

       var groupRunner = new GroupRunner(cancellationToken, PauseBlock); 

       if (engGroup.FireAndForget) 
        groupRunner.RunGroup(engGroup); 
       else 
        await groupRunner.RunGroup(engGroup); 
      } 
      return; 
     } 
     catch (OperationCanceledException) 
     { 
      return ; 
     } 
    } 

Thnx给大家。 如果您有任何关于改进的建议,我希望看到它。

+0

您需要分享更多代码... –

+0

您可以在调用'Run'方法的代码行上使用await吗?另外...你可以尝试在'Task.WhenAll ...'上设置'await'而不将'Run'标记为'async'吗? – HuorSwords

+0

@Huor剑没有异步:)没有等待 – Gintaras

回答

0

试试这个:

Run().ConfigureAwait(false); 

public async Task Run() 
{ 
    ... 
    await Task.WhenAll(_workers).ContinueWith(_ => DoneEvent); 
} 

因此,这将告诉它并不需要再次返回到当前线程并完成对什么都线程它去到执行运行。它不会阻塞主线程。

但是我必须警告你,任何在“DoneEvent”上运行的代码都会在另一个线程上执行,所以如果你有任何影响UI线程的代码,你将会得到一个无效的跨线程访问例外。

+0

这没有帮助。当暂停时,应用程序冻结。 – Gintaras

+0

那么消费到底做了什么?你能否更新你的帖子以显示更多? –