正在等待TaskCompletitionSource不良做法

问题描述 投票:0回答:1

我必须在这里补充一下,我不是Stackoverflow的实践提问者,因此,我很高兴收到有关为何我的问题可能不适合此处的反馈。

等待TaskCompletitionSource不好做吗?

这是我的用例:

我有一个处理程序类,该类在事件发生时调用函数Func<T, Task>回调。有两种方法A和B用作回调。 A在这里调用异步HTTP客户端,B在这里进行计算。在这两种情况下,await调用都会解冻UI,然后更新属性。

A:

result = await CallHttpClient(...) // unfreeze UI
// ... copy image bytes and update UI (long running not async)
// release bytes in calling method

B:

var  tcs = new TaskCompletionSource<bool>();
await tcs.Task; // unfreeze UI
// ... copy image bytes and update UI (long running not async)
tcs.SetResult(true); // release bytes in calling method

我的问题在这里,使用TaskCompletionSource封装非异步调用是否是一种不好的做法?

该文档规定以下内容。

如果要为现有的异步操作或事件创建任务包装,请使用TaskCompletionSource。 https://docs.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming

另一种可能性是调用Task.Run(),但对我来说感觉更糟。不使用Async会导致UI冻结,虽然这可能是最干净的解决方案,但这并不是我真正想要的UI。

c# .net task-parallel-library taskcompletionsource
1个回答
0
投票

[如果没有某种多线程,就无法在后台执行CPU绑定任务。

此代码...

var  tcs = new TaskCompletionSource<bool>();
await tcs.Task; // unfreeze UI
// ... copy image bytes and update UI (long running not async)
tcs.SetResult(true); // release bytes in calling method

...将阻塞await,因为直到之后才调用SetResult,从而导致某种死锁。

我想你可以像这样做些疯狂的事情

var  tcs = new TaskCompletionSource<bool>();
Parallel.Invoke
(
    () => await tcs.Task,
    () => {
         // ... copy image bytes and update UI (long running not async)
        tcs.SetResult(true); // release bytes in calling method
    }
);

但是我不确定这是否也可以。执行此操作的标准方法是

await Task.Run( () => {
    // ... copy image bytes and update UI (long running not async)
});

...这当然更容易理解,并且它的含义是Task.Run()

© www.soinside.com 2019 - 2024. All rights reserved.