Async Sub () или Async Function () как задача для огня и забыть? - PullRequest
0 голосов
/ 13 февраля 2019

Я хочу сделать что-то асинхронно, и мне плевать на результат.
Какой лучший способ сделать это?

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 голосов
/ 13 февраля 2019

Основные причины для использования Function, который возвращает Task, а не Async Sub, двояки.Первое - это обработка исключений.Если вы сделаете что-то подобное, вы получите неперехваченное исключение, которое прекратит работу вашего приложения:

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

Вторая большая причина в том, что, хотя вам это может и не понадобиться сейчас, оно может вам понадобитьсяпотом.Если это уже функция, которая возвращает задачу, то вы можете использовать ее по своему усмотрению.Если вы этого не сделаете, вы не можете ожидать этого, или планировать события, которые будут происходить после него, или прерывать его, или делать любые другие вещи, которые вы можете делать с задачами.Таким образом, вопрос на самом деле не «зачем это делать?», А «почему бы не сделать это?»

Например, это выдает «Здесь», за которым следует «Готово»:

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 из области видимости.Задача будет продолжаться, даже если на нее ничего не ссылается.Например:

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
...