[英]How To Using Dataflow With Only BroadcastBlock And ActionBlock
This is my first question in SO, i'm new using DataFlow with BroadcastBlock and ActionBlock, i hope i can get solution in here.这是我在 SO 中的第一个问题,我是使用带有 BroadcastBlock 和 ActionBlock 的 DataFlow 的新手,我希望我能在这里找到解决方案。 Here's the structure.
这是结构。
class SampleModel
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public bool Success { get; set; } = true;
public object UniqueData { get; set; }
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"Id - {Id}");
sb.AppendLine($"Success - {Success}");
sb.AppendLine($"UniqueData - {UniqueData}");
string tmp = sb.ToString();
sb.Clear();
return tmp;
}
}
class CreateDownloadTask
{
public async Task VeryLongProcess()
{
await Task.Run(async () =>
{
Console.WriteLine("Long Process Working..");
await Task.Delay(TimeSpan.FromSeconds(5));
Console.WriteLine("Long Process Done..");
});
}
public async Task CreateSimpleBroadcastX<T>(T data)
{
Action<T> process = async model =>
{
Console.WriteLine("Working..");
await VeryLongProcess();
Console.WriteLine("Done");
};
var broad = new BroadcastBlock<T>(null);
var action = new ActionBlock<T>(process);
var dflo = new DataflowLinkOptions { PropagateCompletion = true };
broad.LinkTo(action, dflo);
await broad.SendAsync(data);
broad.Complete();
await action.Completion.ContinueWith(async tsk =>
{
Console.WriteLine("Continue data");
}).ConfigureAwait(false);
Console.WriteLine("All Done");
}
}
var task = cdt.CreateSimpleBroadcastX<SampleModel>(new SampleModel
{
UniqueData = cdt.GetHashCode()
});
task.GetAwaiter().GetResult();
Console.WriteLin("Completed");
Working..
Long Process Working..
Long Process Done..
Done
Continue data
All Done
Completed
Working..
Long Process Working..
Continue data
All Done
Completed
Long Process Done..
Done
This is happen when ther is async-await
inside of ActionBlock.当 ActionBlock 中有
async-await
时会发生这种情况。 Now, the question is, is that possible to make the result as i expected without WaitHandle
?现在,问题是,在没有
WaitHandle
情况下,是否有可能达到我预期的结果?
That mean, ActionBlock.Completion will be wait until the Action
or Delegate
inside the ActionBlock is complete executed?那就是说,ActionBlock.Completion 会一直等到 ActionBlock 中的
Action
或Delegate
执行完毕?
Or i'm i doing it wrong with that patter?还是我用那个模式做错了?
Thanks in Advance, and sorry for my bad english.提前致谢,并为我的英语不好而感到抱歉。
Your problem is here:你的问题在这里:
Action<T> process = async model => ...
That code creates an async void
method, which should be avoided .该代码创建了一个
async void
方法, 应该避免使用。 One of the reasons you should avoid async void
is because it is difficult to know when the method has completed.您应该避免
async void
的原因之一是因为很难知道该方法何时完成。 And this is exactly what is happening: the ActionBlock<T>
cannot know when your delegate has completed because it is async void
.这正是正在发生的事情:
ActionBlock<T>
无法知道您的委托何时完成,因为它是async void
。
The proper delegate type for an asynchronous method without a return value that takes a single argument is Func<T, Task>
: 没有返回值且接受单个参数的异步方法的正确委托类型是
Func<T, Task>
:
Func<T, Task> process = async model => ...
Now that the asynchronous method returns a Task
, the ActionBlock
can know when it completes.现在异步方法返回一个
Task
, ActionBlock
可以知道它何时完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.