Vb.net Async Sub()或Async Function()作为Fire and Forget的任务?

Vb.net Async Sub()或Async Function()作为Fire and Forget的任务?,vb.net,asynchronous,async-await,task,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 每个人都告诉我使用函数作为任务,但由于我没

我想异步做一些事情,不在乎结果。
最好的方法是什么

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
每个人都告诉我使用
函数作为任务
,但由于我没有等待它,我总是在VS.

有什么区别?为什么要这样做?

使用返回任务的
函数而不是
异步子函数的主要原因有两个。第一个是异常处理。如果您这样做,您将得到一个未捕获的异常,它将终止您的应用程序:

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
该异常不会被Try/Catch块捕获,因为它是在一个单独的线程上抛出的

但是,如果您这样做,它将被捕获并处理:

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
第二大原因是,即使你现在可能不需要它,但你以后可能需要它。如果它已经是一个返回任务的函数,那么您可以任意使用它。如果你不这样做,你就不能等待它,或者安排事情在它之后发生,或者中止它,或者做任何其他你可以用任务做的事情。所以,问题其实不是“为什么要这样做?”,而是“为什么不这样做?”

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

正如其他人提到的,为了避免警告,您可以将任务分配给如下变量:

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

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

Public Sub DoSomething()
    Dim t As Task = DoSomethingAsync()
    Console.WriteLine("Done Doing Something")
End Sub

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

Async Sub
仅存在于事件处理程序中。如果它实际上是一个事件处理程序,那么它应该是
Async Sub
,但事件处理程序也应该具有适当的参数。如果它不是一个事件处理程序,它就不应该是
Async Sub
@GSerg这是C#@Fox,没关系。@GSerg你确定吗?当我等待它时,我的处理程序停止了。这就是重点。我想同时做这两件事,你不必等待异步函数。只需分配
任务
它返回到一个变量,然后您可以稍后使用该变量,例如test
IsFaulted
,以查看其中是否引发了异常。@jmchinney问题是,我不能在事件处理程序本身中使用长时间运行的代码。我估计不会超过3秒。异步操作需要10秒以上的时间。当我将任务分配给var时,我以后仍然需要等待它们,对吗?@Fox否,如果不等待任务,它仍然会自己运行,就像
异步子
一样。等待它是可选的。@jmcillhinney但是当我对它进行asign并且处理程序在任务之前结束时,var将被释放,不是吗?
Public Sub Main()
    Dim t As Task = DoSomethingAsync()
    Threading.Thread.Sleep(5000)
    Console.WriteLine("Done")
End Sub
Public Sub Main()
    DoSomething()
    Threading.Thread.Sleep(5000)
    Console.WriteLine("Really Done")
End Sub

Public Sub DoSomething()
    Dim t As Task = DoSomethingAsync()
    Console.WriteLine("Done Doing Something")
End Sub

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