gpt4 book ai didi

c# - 在服务中使用 Task.Run 作为同步方法

转载 作者:太空狗 更新时间:2023-10-29 21:43:33 24 4
gpt4 key购买 nike

我已经阅读了很多关于异步编程的文章,但我不确定一件事。我有第 3 方 winrt 库,用 C++ 编写,我想包装它。所以现在我有:

public Task LoginAsync(){
return Task.Run(winrtLibrary.Login();)
}

根据 Stephen Cleary 和 Stephen Toub 的博客,这不是好的解决方案。但是当我同步使用该方法时,我的 UI 将无响应并被阻塞。同步公开服务方法并在 UI 中使用 Task.Run 是否更好?

最佳答案

Stephen Toub 是什么意思

do not use Task.Run in the implementation of the method; instead, use Task.Run to call the method

你不应该使用 Task.Run 吗?隐藏异步方法背后的 CPU 绑定(bind)工作(Task 返回方法)。如果您需要包装外部代码,请将其隐藏在反射(reflect)此代码功能的界面后面。任何异步 I/O 都可以(并且应该)公开为 Task返回方法,并且 CPU 绑定(bind)的工作必须使用适当的 API 公开。让代码的使用者自己决定如何使用该代码。当您碰巧也被消费者使用时,请使用Task.Run运行您的同步代码(现在通过接口(interface)包装和公开)很明显您正在卸载 CPU 绑定(bind)工作。例如,在 UI 应用程序中,您应该调用 Task.Run在您的 UI 层(而不是在您的 BL 甚至 DA 层的深处),很明显 UI 卸载了一些 CPU 绑定(bind)的工作。


Why do you think, that I shouldn't call Task.Run in BL? What if I have ViewModel, which references BL and BL references service layer (in my case is it wrapper).

我认为方法签名应该准确反射(reflect)方法的作用。我能做的就是将您重定向回 Cleary's article :

When a developer sees two methods in an API winrtLibrary.Login() and winrtLibrary.LoginAsync(), the convention is that they represent a naturally-asynchronous operation. In other words, the developer expects that winrtLibrary.LoginAsync() is the “natural” implementation and that winrtLibrary.Login() is essentially a synchronous (blocking) equivalent of that operation. That API implies that winrtLibrary.Login will at some point have the calling thread enter a wait state as it blocks for the naturally-asynchronous operation to complete.

如果您将方法签名为 public Task OffloadLoginToTheThreadPool(),您仍然可以将同步代码隐藏在异步方法后面并遵循 Cleary 的经验法则.但我认为(显然 Cleary 也是)简单调用 Task.Run 的替代方案从 UI(或 Controller )中获取是一种更好的方法,它遵循清洁代码的原则。

关于c# - 在服务中使用 Task.Run 作为同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38116640/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com