异步Sub()或Async Function()作为“解雇”任务?

时间:2019-02-13 14:01:26

标签: vb.net asynchronous async-await task

我想异步地做某事,而不关心结果。
最好的方法是什么?

Public Async Function HandlerForSomeEvent() As Task
  'This is where I do stuff

  'Then this is stuff I want to do without waiting for it
  DoStuff()

  'Here I continue doing other stuff
End Function
Async Sub DoStuff()
  'Doing stuff while the handler continues doing it's stuff
End Sub

'VS

Async Function DoStuff() As Task
  'Doing stuff while the handler continues doing it's stuff
End Function

每个人都告诉我使用Function As Task,但是由于我不等待它,所以我总是在VS中收到烦人的警告。
有什么区别,为什么我应该这样做?

1 个答案:

答案 0 :(得分:1)

使用返回Function而不是Task的{​​{1}}的主要原因有两个。首先是异常处理。如果您执行以下操作,则会收到未捕获的异常,该异常将终止您的应用程序:

Async Sub

Try / Catch块不会捕获该异常,因为它是在单独的线程上引发的。

但是,如果执行此操作,它将被捕获并处理:

Public Sub Main()
    Try
        DoSomethingAsync()
    Catch ex As Exception
        Console.WriteLine(ex)
    End Try
End Sub

Private Async Sub DoSomethingAsync()
    Throw New Exception()
End Sub

第二个大原因是因为,即使您现在可能不需要它,但稍后您可能也需要它。如果已经是可以返回任务的函数,则可以按照自己的意愿使用它。如果不这样做,您将无法等待它,也无法计划发生在它之后的事情,或者中止它,或者执行任务可以执行的其他任何事情。因此,问题实际上不是“为什么要做?”,而是“为什么不这样做?”

例如,这将输出“ Here”,然后输出“ Done”:

Public Async Sub Main()
    Try
        Await DoSomethingAsync()
    Catch ex As Exception
        Console.WriteLine(ex)
    End Try
End Sub

Private Async Function DoSomethingAsync() As Task
    Throw New Exception()
End Sub

就像其他人提到的那样,为了避免警告,您可以将任务分配给这样的变量:

Public Sub Main()
    DoSomethingAsync()
    Threading.Thread.Sleep(5000)
    Console.WriteLine("Done")
End Sub

Public Async Function DoSomethingAsync() As Task
    Console.WriteLine("Here")
End Function

无论哪种方式都可以工作,并且可以在自己的线程上运行,就像Public Sub Main() Dim t As Task = DoSomethingAsync() Threading.Thread.Sleep(5000) Console.WriteLine("Done") End Sub 一样。 Async Sub变量是否超出范围也无关紧要。即使没有引用,该任务也将继续运行。例如:

Task