ActionBlock이있는 Receiver 클래스가 있습니다.
public class Receiver<T> : IReceiver<T>
{
private ActionBlock<T> _receiver;
public Task<bool> Send(T item)
{
if(_receiver!=null)
return _receiver.SendAsync(item);
//Do some other stuff her
}
public void Register (Func<T, Task> receiver)
{
_receiver = new ActionBlock<T> (receiver);
}
//...
}
ActionBlock에 대한 Register-Action은 await-Statement가있는 async-Method입니다.
private static async Task Writer(int num)
{
Console.WriteLine("start " + num);
await Task.Delay(500);
Console.WriteLine("end " + num);
}
이제는 작업 메서드가 끝날 때까지 조건이 설정되어 있으면 독점적 인 동작을 얻기 위해 동 기적으로 대기해야합니다.
var receiver = new Receiver<int>();
receiver.Register((Func<int, Task) Writer);
receiver.Send(5).Wait(); //does not wait the action-await here!
문제는 "기다리는 Task.Delay (500);" 문이 실행되면 "receiver.Post (5) .Wait ();" 더 이상 기다리지 않는다.
여러 변종 (TaskCompletionSource, ContinueWith, ...) 시도했지만 작동하지 않습니다.
누구든지 문제를 해결하는 방법을 알고 있습니까?
ActionBlock
기본적으로 독점적 인 비헤이비어가 적용됩니다 (한 번에 하나의 항목 만 처리됨). "독점적 인 행동"으로 다른 것을 의미한다면,TaskCompletionSource
작업이 완료되면 발신자에게 알립니다.
... use ActionBlock<Tuple<int, TaskCompletionSource<object>>> and Receiver<Tuple<int, TaskCompletionSource<object>>>
var receiver = new Receiver<Tuple<int, TaskCompletionSource<object>>>();
receiver.Register((Func<Tuple<int, TaskCompletionSource<object>>, Task) Writer);
var tcs = new TaskCompletionSource<object>();
receiver.Send(Tuple.Create(5, tcs));
tcs.Task.Wait(); // if you must
private static async Task Writer(int num, TaskCompletionSource<object> tcs)
{
Console.WriteLine("start " + num);
await Task.Delay(500);
Console.WriteLine("end " + num);
tcs.SetResult(null);
}
또는AsyncLock
(내 AsyncEx 라이브러리에 포함) :
private static AsyncLock mutex = new AsyncLock();
private static async Task Writer(int num)
{
using (await mutex.LockAsync())
{
Console.WriteLine("start " + num);
await Task.Delay(500);
Console.WriteLine("end " + num);
}
}
AsyncLock
. 코드 샘플에 대한 업데이트 된 답변보기 항목이 처리 완료 시점을 더 이상 알지 못하지만 각 항목은 한 번에 하나씩 처리됩니다 (async
처리). - Stephen Cleary
_receiver
~로TransformBlock
다음 행동을 새로운 것에 넣으십시오.ActionBlock
, 연결_receiver
? - svick