プロデューサーとコンシューマーの乗算タスク クラスがあります。私は方法を持っています:
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にして await beforeを追加したこと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. 改善すべき点について何か提案があれば、私はそれを見たいと思います。