如何在vb.net中进行一个非常简单的异步方法调用

时间:2012-05-01 13:38:33

标签: vb.net asynchronous

我只是有一个简单的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

3 个答案:

答案 0 :(得分:22)

除非您需要对线程进行更多控制,否则我建议不要使用Thread类,因为创建和拆除线程非常昂贵。相反,我建议使用a ThreadPool threadSee this以获得良好的阅读。

您可以在ThreadPool线程上执行此方法,如下所示:

System.Threading.ThreadPool.QueueUserWorkItem(AddressOf DoAsyncWork)

您还需要将方法签名更改为...

Protected Sub DoAsyncWork(state As Object) 'even if you don't use the state object

最后,还要注意其他线程中未处理的异常会导致IIS死亡。请参阅this article(旧的但仍然相关;不确定解决方案,因为我不能使用ASP.NET)。

答案 1 :(得分:7)

你可以用一个简单的线程来做到这一点:

添加:

 Imports System.Threading

无论您希望它在哪里运行:

 Dim t As New Thread(New ThreadStart(AddressOf DoAsyncWork))
 t.Priority = Threading.ThreadPriority.Normal
 t.Start()

t.Start()的调用立即返回,新线程在后台运行DoAsyncWork,直到完成为止。你必须确保该调用中的所有内容都是线程安全的,但乍一看它似乎已经是如此。

答案 2 :(得分:0)

这是一个较旧的线程,但是我认为无论如何我都会添加它,因为我最近需要解决这个问题。如果要使用ThreadPool来调用带有参数的方法,则可以如下修改@ Timiz0r的示例:

System.Threading.ThreadPool.QueueUserWorkItem(Sub() MethodName( param1, param2, ...))