简体   繁体   English

将Task.Run用于服务中的同步方法

[英]Using Task.Run for synchronous method in service

I've read a lot of articles about asynchronnous programming, but I'm not sure in one thing. 我已经阅读了很多有关异步编程的文章,但是我不确定一件事。 I have 3rd party winrt library, written in C++ and I want to wrapp it. 我有用C ++编写的3rd party winrt库,我想包装一下。 So now I have: 所以现在我有:

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

According Stephen Cleary and Stephen Toub blogs, it is not good solution. 根据Stephen Cleary和Stephen Toub的博客,这不是一个好的解决方案。 But when I use the method synchronously, my UI will not be responsive and will be blocked. 但是,当我同步使用该方法时,我的UI将不会响应,并且将被阻止。 Is it better to expose service method synchronously and in UI use Task.Run? 最好是同步公开服务方法并在UI中使用Task.Run吗?

What Stephen Toub means by Stephen Toub的意思是

do not use Task.Run in the implementation of the method; 在该方法的实现中不要使用Task.Run; instead, use Task.Run to call the method 而是使用Task.Run来调用该方法

Is that you shouldn't use Task.Run to hide CPU bound work behind async methods ( Task returning methods). 是您不应该使用Task.Run将CPU绑定的工作隐藏在异步方法( Task返回方法)之后。 If you need to wrap external code, hide it behind an interface which reflects what this code do. 如果需要包装外部代码,请将其隐藏在反映此代码功能的接口后面。 Any asynchronous I/O can (and should) be exposed as Task returning methods, and CPU bound work must be exposed with the proper API. 任何异步I / O都可以(并且应该)作为Task返回方法公开,并且必须使用适当的API公开与CPU绑定的工作。 Let the consumers of your code to decide for themselves how to use that code. 让您的代码使用者自行决定如何使用该代码。 When you happen to by the consumer too, use Task.Run to run your synchronous code (now wrapped and exposed via interface) where it is very clear that you are offloading CPU bound work . 当用户碰巧遇到这种情况时,也可以使用Task.Run运行您的同步代码(现在已经通过接口包装并公开)了,很明显,您正在卸载CPU绑定的工作 In UI apps, for example, you should call Task.Run in your UI layer (and not deep down in your BL or even DA layers), where it is very clear that the UI offloads some CPU bound work. 例如,在UI应用程序中,应在UI层(而不是在BL层甚至DA层中)调用Task.Run ,这很明显,UI减轻了一些CPU限制的工作。


Why do you think, that I shouldn't call Task.Run in BL? 您为什么认为我不应该在BL中调用Task.Run? What if I have ViewModel, which references BL and BL references service layer (in my case is it wrapper). 如果我有ViewModel,该模型引用BL,而BL引用服务层(在我的情况下是包装),该怎么办?

I think that a method signature should reflect exactly what the method does. 我认为方法签名应准确反映该方法的作用。 The best I can do is to redirect you back to Cleary's article : 我能做的最好的就是将您重定向回Cleary的文章

When a developer sees two methods in an API winrtLibrary.Login() and winrtLibrary.LoginAsync(), the convention is that they represent a naturally-asynchronous operation . 当开发人员在API winrtLibrary.Login()和winrtLibrary.LoginAsync()中看到两个方法时, 约定是它们代表自然异步操作 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. 换句话说,开发人员期望winrtLibrary.LoginAsync()是“自然”的实现,并且winrtLibrary.Login()本质上是该操作的同步(阻塞)等效项。 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. 该API表示winrtLibrary.Login会在某个时刻使调用线程进入等待状态,因为它阻塞了自然异步操作的完成。

You can still hide synchronous code behind async method and follow Cleary's rule of thumb, if you sign your method as public Task OffloadLoginToTheThreadPool() . 如果您将方法签名为public Task OffloadLoginToTheThreadPool() ,则仍然可以将同步代码隐藏在async方法后面,并遵循Cleary的经验法则。 But I think (and apparently Cleary, too) that the alternative of simply calling Task.Run from the UI (or Controller) is a much better approach, and it follows the principles of Clean Code. 但是我认为(而且显然也是Cleary),从UI(或控制器)简单调用Task.Run的替代方法是一种更好的方法,它遵循了Clean Code的原理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在同步方法中运行没有 Wait() 的 Task.Run() 有什么影响? - What are the implications of running Task.Run() without Wait() in a synchronous method? 在foreach循环中使用Task.Run和Synchronous方法 - Use Task.Run with Synchronous method inside a foreach loop 使用Task.Run写一个异步方法 - Using Task.Run to write an asynchronous method 使用Task.Run异步调用方法 - Calling a method asynchronously using Task.Run 在同步方法中使用Task.Run()以避免异步方法等待死锁? - Use Task.Run() in synchronous method to avoid deadlock waiting on async method? C#,使用Task.Run运行方法,但代码未执行 - C#, Using Task.Run to run method, but the code is not executing 使用await Task.Run()的Asyc方法永远不会“完成” - Asyc method using await Task.Run() never “completes” 使用Task.Run的Fire&Forget方法不起作用 - Fire & Forget method using Task.Run not working 您可以通过在控制器中使用同步代码上的Task.Run来提高吞吐量吗? - Can you increase throughput by using Task.Run on synchronous code in a controller? 为什么我更喜欢使用API​​异步功能而不是用Task.Run包装同步功能? - Why should I prefer using API async fucntions over wrapping synchronous ones with Task.Run?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM