异步/等待方法的正确方法,包括Lambda(Proper approach on async/await method including Lambda)

编程入门 行业动态 更新时间:2024-10-27 13:29:39
异步/等待方法的正确方法,包括Lambda(Proper approach on async/await method including Lambda)

我想展示两种关于异步编程的范例,并倾听您的​​意见。

一个。

比方说,您已经在库中创建了如下的方法来从GUI客户端使用它。

public async Task<TestObject> DoSomeWork(string aParam1, object aParam2) { TestObject testObj = new TestObject(); ...fill in params to testObj... await MethodCallAsync(testObj); ....do other work synchronous..... ....continue fill testObj properties... await Task.Delay(1000) // just a delay for no reason ...continue synchronous work..... return testObj; }

好的,但是这会把我的GUI上下文切成小的调用片断,对吧? 或者我不知道从你声明一个异步方法的那一刻起它是否会为所有的操作创建一个Task?

如果是,那么很好,没问题,我们可以宣布它异步并继续我们的生活。

让我们说不,我想采取以下的方法,所以我不会打扰GUI,直到我的整个方法调用结束并采取结果,所以在我的调用方法中做一些事情。

B.

另一种方法是。

public async Task<TestObject> DoSomeWork(string aParam1, object aParam2) { TestObject testObj = new TestObject() ..fill state params.... return await Task.Factory.StartNew((state) => { //But now I need to do async/await in here // is it a good practice to async await lambdas? // async/await practices say it's ok as long sas it is not becoming async void // which in our case is not. await MethodCallAsync(testObj); ....do other work synchronous..... ....continue fill state properties... await Task.Delay(1000) // just a delay for no reason ...continue synchronous work..... return state; // Our state and TestObject to examine after completion }, testObj); }

我们现在的问题不仅在于我们应该对lambda进行异步化,而是说你会这样做,它会返回一个Task<Task<TestObject>>而且我们绝对不希望这样。

你应该在管道中调用它,很可能是你的GUI类。

private async void SomethingClickedOrTouched(object sender, EventArgs e) { await RunThisAsyncToDoYourJob(); } private async Task RunThisAsyncToDoYourJob() { TestObject testObj = await myObject.DoSomeWork("param1", anotherObject); }

它只是让我感到有些迷惑,我真的想要详细了解异步编程。

那么,无论如何,A范式是否是正确的方法,并且只有在代码内部的任务lambda完全同步时才使用B范例? 先谢谢你。

问候。

I would like to show two paradigms about async programming and listen to your comments.

A.

Let's say you have created a method like the following in a library to use it from your GUI clients.

public async Task<TestObject> DoSomeWork(string aParam1, object aParam2) { TestObject testObj = new TestObject(); ...fill in params to testObj... await MethodCallAsync(testObj); ....do other work synchronous..... ....continue fill testObj properties... await Task.Delay(1000) // just a delay for no reason ...continue synchronous work..... return testObj; }

Ok, but this will chop my GUI context into small calling pieces, right? or I don't know if from the moment you declare a method async it will create a Task for all the operations inside?

If yes then great, no problem we can just declare it async and move on with our lives.

Lets say no and I would like to take the following approach so I won't disturb the GUI at all until my whole method call finishes and take the result so do something in my calling method.

B.

Another approach would be.

public async Task<TestObject> DoSomeWork(string aParam1, object aParam2) { TestObject testObj = new TestObject() ..fill state params.... return await Task.Factory.StartNew((state) => { //But now I need to do async/await in here // is it a good practice to async await lambdas? // async/await practices say it's ok as long sas it is not becoming async void // which in our case is not. await MethodCallAsync(testObj); ....do other work synchronous..... ....continue fill state properties... await Task.Delay(1000) // just a delay for no reason ...continue synchronous work..... return state; // Our state and TestObject to examine after completion }, testObj); }

Our problem now it's not only if we should asyncify the lambda, say you do it, it the will return a Task<Task<TestObject>> and definitely we don't want that.

You should call this up in the pipeline, most probably your GUI class.

private async void SomethingClickedOrTouched(object sender, EventArgs e) { await RunThisAsyncToDoYourJob(); } private async Task RunThisAsyncToDoYourJob() { TestObject testObj = await myObject.DoSomeWork("param1", anotherObject); }

It just bugs me a little and I really want into detail with async programming.

So, is A paradigm the correct approach anyway, and use the B paradigm only when the Task lambda inside code is completely synchronous? Thank you in advance.

Regards.

最满意答案

编写async方法的正确方法是在不需要恢复捕获的上下文时使用ConfigureAwait(continueOnCapturedContext: false) 。 这通常是针对所有“库”代码完成的。

这将把我的GUI上下文切成小的调用片断,对吧?

是的(因为你没有使用ConfigureAwait )。

或者我不知道从你声明一个异步方法的那一刻起它是否会为所有的操作创建一个Task?

是的, async将创建一个代表async方法的Task 。 然而,有一个Task事实并不意味着它的代码运行在后台线程上。

它会返回一个Task<Task<TestObject>>并且我们绝对不想这样做。

我想知道每个人都在使用Task.Factory.StartNew获取异步任务的想法。 如果你想在后台线程上运行代码, Task.Run是优越的 。


我在我的博客上有一个async介绍 ,可能会对您有所帮助。

The proper way to write an async method is to use ConfigureAwait(continueOnCapturedContext: false) whenever you don't need to resume on the captured context. This is normally done for all "library" code.

this will chop my GUI context into small calling pieces, right?

Yes (since you're not using ConfigureAwait).

or I don't know if from the moment you declare a method async it will create a Task for all the operations inside?

Yes, async will create a Task that represents the async method. However, the fact that there is a Task does not mean that its code is running on a background thread.

it the will return a Task<Task<TestObject>> and definitely we don't want that.

I'd like to know where everyone is getting the idea of using Task.Factory.StartNew for asynchronous tasks. Task.Run is superior if you want to run code on a background thread.


I have an async intro on my blog that you may find helpful.

更多推荐

本文发布于:2023-07-30 01:24:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1321363.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:方法   正确   Proper   Lambda   approach

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!