【问题标题】:How to do a task after another task in vb.net?如何在 vb.net 中完成另一个任务?
【发布时间】:2019-04-29 19:23:55
【问题描述】:
    For Each account In _accounts11
        Dim newtask = account.readbalancesAsync()
        newtask = newtask.ContinueWith(Sub() account.LogFinishTask("Getting Balances", starttime))
        newtask = newtask.ContinueWith(Async Function() account.getOrdersAsync())
        newtask = newtask.ContinueWith(Sub() account.LogFinishTask("Getting Orders", starttime))

        tasklist.Add(newtask)
    Next


    Await Task.WhenAll(tasklist.ToArray)
    Dim b = 1

基本上,对于每个帐户,我都想做 account.readbalancesAsync,然后再做 account.getOrdersAsync()

我留下了代码 newtask.ContinueWith(Sub() account.LogFinishTask("Getting Balances", starttime)) 以表明我知道 ContinueWith 的工作原理。但是,在那之后,我需要继续执行另一项任务。

我该怎么做?

我想做的是这样的

    For Each account In _accounts11
        await account.readbalancesAsync()
        account.LogFinishTask("Getting Balances", starttime)
        await account.getOrdersAsync())
        account.LogFinishTask("Getting Orders", starttime)

        tasklist.Add(newtask)
    Next

显然,如果我这样做,那么一个帐户必须等待另一个帐户完成。我希望所有帐户并行运行。

或者我们看看这段代码

dim response1 = await client.GetAsync("http://example.com/");
dim response2 = await client.GetAsync("http://stackoverflow.com/");

说我是这样做的

dim newtask = client.GetAsync("http://example.com/").continueWith(....)
await newtask

我应该放什么......

【问题讨论】:

  • 您已经开始多次执行后续任务。是什么阻止您继续拨打ContinueWith?虽然我真的很想知道你为什么首先使用所有这些延续任务,而不是仅仅将所有内容包装在 Sub()/End Sub lambda 块中?由于每个任务都已经在后台运行,因此创建更多的任务是没有意义的。
  • 基本上,对于每个帐户,我想做await account.readbalancesasync,然后是await account.getordersasync。但是,我希望它们并行运行而不是串行运行。
  • 我知道如何将 continueWith 与非阻塞正常功能一起使用。现在我想将 continueWith 与异步函数一起使用。

标签: vb.net task continuewith


【解决方案1】:

我认为你在某个地方错误地转错了方向。如果您需要依次运行这四个语句,但又不干扰循环,您只需创建一个执行多行/块 lambda 表达式的一个任务。

例如:

For Each account In _accounts11
    Dim newtask = Task.Run( 'Start a new task.
        Async Function() 'Multiline lambda expression.
            Await account.readbalancesAsync()
            account.LogFinishTask("Getting Balances", starttime)
            Await account.getOrdersAsync()
            account.LogFinishTask("Getting Orders", starttime)
        End Function
    ) 'End of Task.Run()

    tasklist.Add(newtask)
Next

【讨论】:

  • 这是一种方式。你可以用 continueWith 代替吗?
  • @user4951 :请问为什么? ContinueWith 不应该以这种方式使用,并且启动几个类似的新任务会影响性能(即使它可能不明显,也非常没有必要)。
  • 我觉得这有点奇怪。我可以将 continueWith 与正常功能一起使用,但不能将其与可等待功能一起使用。 task.run 也是在同一个线程上运行吗?
  • @user4951 :请描述为什么您不能将ContinueWith 与等待函数一起使用。你期望会发生什么,相反会发生什么? -- 另外,不:Task.Run() 启动一个全新的任务,在操作系统决定运行它的任何线程中运行(请记住:任务可能在不同的线程之间切换,但您可以确定它将始终运行在后台 - 所以不是在同一个线程中)。
  • 常规异步等待在前台运行。您说我可以将 ContinueWith 与等待功能一起使用。我应该怎么做?谢谢。
【解决方案2】:

我只是想在 VisualVincent 的回答中添加一些内容。我还是更喜欢用 continueWith 来做这个

Private Async Function readBalancesAndOrderForEachAccount(starttime As Long) As Task
    Await readbalancesAsync()
    LogFinishTask("Getting Balances", starttime)
    Await getOrdersAsync()
    LogFinishTask("Getting Orders", starttime)
End Function

Public Shared Async Function getMarketDetailFromAllExchangesAsync2() As Task
    Dim CurrentMethod = MethodBase.GetCurrentMethod().Name
    Dim tasklist = New List(Of Task)
    Dim starttime = jsonHelper.currentTimeStamp

...

        For Each account In _accounts11
            Dim newtask = account.readBalancesAndOrderForEachAccount(starttime)
            tasklist.Add(newtask)
        Next
        Await Task.WhenAll(tasklist.ToArray)
        Dim b = 1
   ...
    End Function

这似乎可行。但是,我想了解如何使用 continueWith 执行此操作,因为我很好奇。

【讨论】:

  • 如果您将LogFinishTask 调用移动到各自的方法中,您可以简单地拥有:Dim newtask As Task = readbalancesAsync().ContinueWith(Async Function(t) Return Await getOrdersAsync() End Function)getOrdersAsync() 可以返回 Task(Of Boolean):你只需返回 TrueFalse。请注意,在 VB.Net 中,Function(t) lambda 必须写成 3 行。
  • 你不应该使用ContinueWith;这是low-level, dangerous methodAwait 在各方面都好得多。
  • ContinueWith 非常适合我。我只是不能用等待功能来做到这一点
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
  • 1970-01-01
  • 1970-01-01
  • 2012-01-17
  • 1970-01-01
  • 2013-03-22
  • 1970-01-01
相关资源
最近更新 更多