Task.Run 和 JoinableTaskFactory.Run 之间有什么区别?

huangapple go评论73阅读模式
英文:

What's the difference between Task.Run and JoinableTaskFactory.Run?

问题

假设我有一个需要从非异步方法调用的异步方法/任务,我可以使用JoinableTaskFactory来做到这一点,类似于这样:

```csharp
var jtf = new JoinableTaskFactory(new JoinableTaskContext());
var serviceResponse = jtf.Run(async () => await _service.UpdateSomethingAsync(requestObject));

它与这种方式有何不同:

var task = System.Threading.Tasks.Task.Run(async () => await _service.UpdateSomethingAsync(requestObject));
var serviceResponse = task.Result;

或者这种方式:

ServiceResponse serviceResponse = null;

var task = Task.Run(async () => serviceResponse = await _service.UpdateSomethingAsync(requestObject));
Task.WaitAll(task);

如果我有一个需要从非异步方法执行的任务,实际上有哪些最好的方法可供选择?


<details>
<summary>英文:</summary>

Supposing I have an async method/a task that I need to invoke from a non-async method, and I could do this using the JoinableTaskFactory, something like this:

var jtf = new JoinableTaskFactory(new JoinableTaskContext());
var serviceResponse = jtf.Run(async () => await _service.UpdateSomethingAsync(requestObject));


How is it different from this:

var task = System.Threading.Tasks.Task.Run(async () => await _service.UpdateSomethingAsync(requestObject));
var serviceResponse = task.Result;


Or this:

ServiceResponse serviceResponse = null;

var task = Task.Run(async () => serviceResponse = await _service.UpdateSomethingAsync(requestObject));
Task.WaitAll(task);


If I have a task that I need to execute from a non async method, what&#39;s actually the best way to do this, as there are quite a few options available?

</details>


# 答案1
**得分**: 2

我正在复制并粘贴[1]中的一条评论,该评论来自Andrew Arnott,与[2]中的GitHub问题 loosel 相关。这可能会让您了解为什么[`JoinableTaskFactory`][3]类存在。

&gt; 考虑一个需要UI线程完成的值工厂。它通过`AsyncLazy&lt;T&gt;.GetValueAsync`(在任意线程上)调用。现在,在值工厂能够到达UI线程之前(即使它在UI线程上启动,但在需要之前已经产生),UI线程决定阻塞,直到某些异步操作完成,如果该异步操作仅在值工厂完成后才能完成,则必须允许值工厂进入UI线程以避免死锁。这需要对阻塞UI线程的任何内容进行仔细的依赖跟踪,以知道它需要允许进入以避免死锁的工作,但同时避免让无关的工作进入,这可能会导致崩溃、挂起、数据损坏等。这就是`JoinableTaskFactory`的目的,也是为什么我们需要一个`JoinableTaskFactory`-aware的`AsyncLazy&lt;T&gt;`,以便按规则行事,避免出现此类问题。

还有来自[另一条评论][4]:

&gt; &gt; 与vs-threading的问题在于它是VS特定的。
&gt; 
&gt; 为什么这么说?整个vs-threading库与VS完全独立,而且将始终如此。它还针对.NET Standard,并且我们在.NET Framework和.NET Core上的所有操作系统上运行测试。

&lt;sub&gt;**观点:**如果您想了解我个人对`JoinableTaskFactory`的看法,那就是它是一个旨在解决晦涩问题的晦涩类,很可能不会很快或永远变得流行。&lt;/sub&gt;

[1]: https://github.com/dotnet/runtime/issues/27510#issuecomment-473535054
[2]: https://github.com/dotnet/runtime/issues/27510 "Add async support to System.Lazy"
[3]: https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.threading.joinabletaskfactory
[4]: https://github.com/dotnet/runtime/issues/27510#issuecomment-473429731

<details>
<summary>英文:</summary>

I am copy-pasting [a comment][1] by Andrew Arnott, from a loosely related [GiHub issue][2]. It might give you an idea about why the [`JoinableTaskFactory`][3] class exists.

&gt; Consider a value factory that needs the UI thread to complete. It is invoked through `AsyncLazy&lt;T&gt;.GetValueAsync` (on an arbitrary thread). Now before the value factory is able to reach the UI thread (even if it started on the UI thread, but yielded before needing it), the UI thread decides to block until some async operation is completed, If that async operation will only complete after the value factory completes, then the value factory must be allowed onto the UI thread to avoid a deadlock. This requires some careful dependency tracking for whatever is blocking the UI thread to know which work it needs to allow in to avoid a deadlock, but also avoid letting unrelated work in which can cause crashes, hangs, data corruption, etc. This is what the `JoinableTaskFactory` is all about, and why we need an `AsyncLazy&lt;T&gt;` that is `JoinableTaskFactory`-aware in order to play by the rules and avoid such problems.

Also from [another comment][4]:

&gt; &gt; The problem with vs-threading is that it&#39;s VS specific.
&gt; 
&gt; Why do you say that? The entire vs-threading library is completely independent of VS and it will always be so. It targets .NET Standard as well, and we run tests on all operating systems on both .NET Framework and .NET Core.

&lt;sub&gt;**Opinion:** If you want to know my personal perception about the `JoinableTaskFactory`, is that it&#39;s an obscure class that is intended to solve an obscure problem, and most likely it&#39;s not going to become popular any time soon, if ever.&lt;/sub&gt;

  [1]: https://github.com/dotnet/runtime/issues/27510#issuecomment-473535054
  [2]: https://github.com/dotnet/runtime/issues/27510 &quot;Add async support to System.Lazy&quot;
  [3]: https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.threading.joinabletaskfactory
  [4]: https://github.com/dotnet/runtime/issues/27510#issuecomment-473429731

</details>



huangapple
  • 本文由 发表于 2023年7月13日 22:38:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76680622.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定