异步等待等待所有结果并继续

编程入门 行业动态 更新时间:2024-10-25 00:36:47
本文介绍了异步等待等待所有结果并继续的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

对于如何实现异步等待方法并在继续操作之前等待结果,我有些困惑.

I'm a bit confuse about how to implement async await approach and wait for results before continuing.

我想并行调用3个后端,并等待它们直到响应,然后获取结果并在内部分配它们.像这样:

I want to make 3 calls to backend in parallel and wait for them until they responds then get the result and assign them internally. Something like this:

Private Sub GetParseExpressionResults() If Not isParseExpressionSupported Then Return End If 'Cleaning collections Me.parseExpressionItemsTo.Clear() Me.parseExpressionItemsCC.Clear() Me.parseExpressionItemsSubject.Clear() 'Getting list of document ids Dim docIds As List(Of Integer) = DocumentsToSend.Select(Function(doc) doc.id).ToList() 'Getting all the parse expression and then wait for them Dim taskTo As Threading.Tasks.Task(Of List(Of ParseExpressionItem)) = GetParseExpression(txtTo.Text, docIds) Dim taskCC As Threading.Tasks.Task(Of List(Of ParseExpressionItem)) = GetParseExpression(txtCC.Text, docIds) Dim taskSubject As Threading.Tasks.Task(Of List(Of ParseExpressionItem)) = GetParseExpression(txtSubject.Text, docIds) Threading.Tasks.Task.WaitAll(taskTo, taskCC, taskSubject) Me.parseExpressionItemsTo = taskTo.Result Me.parseExpressionItemsCC = taskCC.Result Me.parseExpressionItemsSubject = taskSubject.Result End Sub Private Async Function GetParseExpression(ByVal text As String, ByVal docIds As List(Of Integer)) As Threading.Tasks.Task(Of List(Of ParseExpressionItem)) If String.IsNullOrEmpty(text) Then Return New List(Of ParseExpressionItem) End If Dim result As List(Of ParseExpressionItem) = ClientActiveSession.Session.getParseExpression(text, docIds) Return result End Function

此代码的问题是等待语句.似乎无法使用它,因此在这种情况下,代码将同步运行,实际上VS向我警告了这一点.预先非常感谢.

The problem with this code is await sentence. It seems is not possible to use it and therefore in this case the code will run synchronously, in effect VS is warning me this. Many thanks in advance.

推荐答案

通常,如果您的过程调用另一个过程,则必须等到另一个过程完成.

Normally if your procedure calls another procedure it has to wait until this other procedure is finished.

有时,在您调用的过程的深处,线程必须闲置地等待另一个进程完成.例如,从数据库查询一些数据,将数据写入文件,从Internet上获取信息,所有线程都只能等待的进程.

Sometimes, deep inside the procedure that you called, the thread has to wait idly for another process to finish. Examples are querying some data from a database, writing data to a file, fetching information from the internet, all processes where your thread can do nothing but wait.

async-await的整个思想是让线程做其他事情,而不是闲着等待.例如,线程可以进入调用堆栈,以查看其中一个调用者是否没有等待.

The whole idea of async-await is to let the thread do something else instead of waiting idly. For instance, the thread can go up the call stack, to see if one of the callers is not waiting.

稍后,当等待的进程完成时,线程(或其他线程)将在等待之后继续处理语句.

Later, when the awaited process is finished, the thread (or a different one) continues processing the statements after the await.

这就是为什么您决定使用async-await的原因:如果您的过程必须等待另一个进程完成,则您的线程可以在过程中执行其他操作,或者在调用者的过程中执行语句.

So this is why you decided to use async-await: if your procedure has to wait for another process to finish, your thread can do other thing, either in your procedure, or execute statements in the procedure of your caller

结构类似于(对不起,我的基本知识有点生锈,我会在C#中完成,但是要点)

The structure is similar to (sorry, my basic is a bit rusty, I'll do it in C#, but you get the gist)

var taskDoIt = DoSomethingAsync(...) // because I am not awaiting, the following statements are executed when DoSomethingAsync // has to wait DoSomethingElse(); // now I need the results of DosomethingAsync, so I'll await: var result = await taskDoIt();

如果在我开始等待时DoSomethingAsync中的等待过程未完成,则线程将在调用后上移至调用堆栈以执行语句,直到看到等待为止.再次向上调用堆栈以查看是否有人等不及.

If the awaited process in DoSomethingAsync is not finished when I start awaiting, the thread goes up my call stack to execute the statements after the call until it sees an await. Up the call stack again to see if there is someone who is not awaiting, etc.

在您的程序中,当您调用等待过程而不等待它们完成时,我们会看到此模式:

In your program we see this pattern when you call awaitable procedures without awaiting them to finish:

Dim taskTo As Threading.Tasks.Task(Of List(Of ParseExpressionItem)) = GetParseExpression(txtTo.Text, docIds)

因为GetParseExpression是异步的,所以我们知道它里面的某个地方正在等待.实际上,如果您忘记在异步函数中等待,编译器会警告您.

Because GetParseExpression is async, we know that somewhere inside it has an await in it. In fact, your compiler will warn you if you forget to await in an async function.

GetParseExpression等待时,您的过程将继续:

As soon as GetParseExpression is awaiting, your procedure continues:

Dim taskCC As Threading.Tasks.Task(Of List(Of ParseExpressionItem)) = GetParseExpression(txtCC.Text, docIds)

直到我们再次等待.继续:

Until we are awaiting again. Continue with:

Dim taskSubject As Threading.Tasks.Task(Of List(Of ParseExpressionItem)) = GetParseExpression(txtSubject.Text, docIds)

直到现在我们还没有等待.任务的结果可能尚不可用.此时,您决定需要这三个函数的结果.

Until now we have not awaited yet. The results of the tasks may not be available yet. At this moment you decide that you need the results of these three functions.

现在是重要的更改:在异步函数中,不要使用Task.WhaitAll,请使用Task.WhenAll

Task.WhenAll 是一个可等待的函数.如果您开始等待它,则该线程将进入调用堆栈,以查看调用者是否有事要做,就像它与任何等待函数一样.

Task.WhenAll is an awaitable function. If you start awaiting for it, the thread goes up the call stack to see if the caller has something to do, just like it does with any awaitable function.

await Threading.Tasks.Task.WhenAll(new Task[] {taskTo, taskCC, taskSubject});

(请翻译成VB)

完成所有三个任务后,可以使用属性 Result 访问任务的等待返回值.

After all three tasks are completed, you can use property Result to access the awaited return values of the tasks.

更多推荐

异步等待等待所有结果并继续

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

发布评论

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

>www.elefans.com

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