Как сделать очень простой асинхронный вызов метода в vb.net
У меня просто простой веб-сайт vb.net, которому нужно вызвать Sub, который выполняет очень длинную задачу, которая работает с синхронизацией некоторых каталогов в файловой системе (подробности не важны).
Когда я вызываю метод, он в конечном итоге истекает на веб-сайте, ожидая завершения подпрограммы. Однако, несмотря на то, что веб-сайт не работает, подпрограмма в конечном итоге завершает работу, и все каталоги заканчиваются так, как должны.
Я хочу просто запретить таймаут, поэтому я бы хотел просто вызвать Sub асинхронно. Мне не нужно (или даже хочу) и обратный вызов/подтверждение того, что он успешно выполнен.
Итак, как я могу назвать свой метод асинхронно внутри веб-сайта с помощью VB.net?
Если вам нужен какой-то код:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Call DoAsyncWork()
End Sub
Protected Sub DoAsyncWork()
Dim ID As String = ParentAccountID
Dim ParentDirectory As String = ConfigurationManager.AppSettings("AcctDataDirectory")
Dim account As New Account()
Dim accts As IEnumerable(Of Account) = account.GetAccounts(ID)
For Each f As String In My.Computer.FileSystem.GetFiles(ParentDirectory)
If f.EndsWith(".txt") Then
Dim LastSlashIndex As Integer = f.LastIndexOf("\")
Dim newFilePath As String = f.Insert(LastSlashIndex, "\Templates")
My.Computer.FileSystem.CopyFile(f, newFilePath)
End If
Next
For Each acct As Account In accts
If acct.ID <> ID Then
Dim ChildDirectory As String = ConfigurationManager.AppSettings("AcctDataDirectory") & acct.ID
If My.Computer.FileSystem.DirectoryExists(ChildDirectory) = False Then
IO.Directory.CreateDirectory(ChildDirectory)
End If
My.Computer.FileSystem.DeleteDirectory(ChildDirectory, FileIO.DeleteDirectoryOption.DeleteAllContents)
My.Computer.FileSystem.CopyDirectory(ParentDirectory, ChildDirectory, True)
Else
End If
Next
End Sub
Ответы
Ответ 1
Я бы не рекомендовал использовать класс Thread
, если вам не нужен намного больше контроля над потоком, так как создание и отключение потоков является дорогостоящим. Вместо этого я бы рекомендовал использовать поток ThreadPool. См. это для хорошего чтения.
Вы можете выполнить свой метод в потоке ThreadPool
следующим образом:
System.Threading.ThreadPool.QueueUserWorkItem(AddressOf DoAsyncWork)
Вам также необходимо изменить свою подпись метода на...
Protected Sub DoAsyncWork(state As Object) 'even if you don't use the state object
Наконец, также помните, что необработанные исключения в других потоках будут убивать IIS. См. в этой статье (старый, но по-прежнему актуальный, не уверен в решениях, хотя, поскольку я не использую ASP.NET).
Ответ 2
Вы можете сделать это с помощью простого потока:
Добавить:
Imports System.Threading
И везде, где вы хотите его запустить:
Dim t As New Thread(New ThreadStart(AddressOf DoAsyncWork))
t.Priority = Threading.ThreadPriority.Normal
t.Start()
Вызов t.Start()
немедленно возвращается, а новый поток запускает DoAsyncWork
в фоновом режиме до завершения. Вы должны убедиться, что все в этом вызове было потокобезопасным, но на первый взгляд это, как правило, уже так.
Ответ 3
Я также искал информацию о асинхронном программировании в VB. В дополнение к этой теме я также нашел следующее: начиная с Visual Studio 2012 и .Net Framework 4.5, VB было предоставлено два новых ключевых слова, чтобы сделать метод асинхронным в декларации без использования Thread или Threadpool. Новые ключевые слова: "Async" и "Await". Вы можете ссылаться на следующие ссылки:
http://msdn.microsoft.com/library/hh191443%28vs.110%29.aspx
https://msdn.microsoft.com/en-us/library/hh191564%28v=vs.110%29.aspx
Ответ 4
Это старая ветка, но я решил, что все равно добавлю к ней, поскольку недавно мне нужно было решить эту проблему. Если вы хотите использовать ThreadPool для вызова метода с параметрами, вы можете изменить пример @Timiz0r следующим образом:
System.Threading.ThreadPool.QueueUserWorkItem(Sub() MethodName( param1, param2, ...))