【问题标题】:Making sure async tasks complete before vb.net application terminates确保在 vb.net 应用程序终止之前完成异步任务
【发布时间】:2017-03-17 16:34:09
【问题描述】:

我正在创建一个 vb.net 桌面应用程序。此应用程序包括一些异步功能。当用户通过右上角的红色 X 关闭应用程序时,有一些逻辑可能运行这些异步函数中的一个或多个。问题是,程序在完成之前就终止了。我认为在通话中使用“Await”可以做到这一点,但显然不是。

我找到了this thread that talks about using ManualResetEvent,但我无法理解所有内容,特别是因为问题是在控制台应用程序的上下文中,而答案链接到的 MSDN 文档是关于指定线程,而不是简单地使用异步任务。作为尝试使用它,我尝试将其添加到我的主表单中:

Public resetEvent As ManualResetEvent = New ManualResetEvent(False)

在调用这些函数之一之后,我立即添加了这个(引用包括调用):

Await activeCount.SerializeAsync(activeCount)
resetEvent.WaitOne()

在我的异步函数本身的末尾,在返回任务之前,添加了这个:

frmMain.resetEvent.Set()

不过,我认为我没有正确使用它。无论如何,程序在完成之前仍然会终止。

甚至在那之前,我认为这样的事情最好的地方是ApplicationEvents MyApplication_Shutdown,但我不确定如何知道这样的功能是否仍在运行。

那么在这种情况下应用程序终止之前确保我的所有异步函数完成的最佳方法是什么?

谢谢!


接受答案后更新:

虽然 F0r3v3r-A-N00b 的回答有效,但我意识到在某些情况下我需要使用对话框。我无法在后台工作人员中调用它,因为对话框位于 GUI 线程上,而不是后台线程上。我试着移动一些东西,所以我会先调用对话框,然后让后台工作人员等等,但无论出于何种原因,我都无法让它工作。

长话短说,我通过简单地制作我的函数的同步版本来解决它,所以我可以说'如果用户终止程序并且我需要在关闭之前调用这些函数中的任何一个,请调用同步版本'。这样可行。谢谢!

【问题讨论】:

    标签: vb.net asynchronous task terminate


    【解决方案1】:

    试试这个。创建一个新项目。将 1 个标签和后台工作人员添加到您的表单中。将此粘贴到表单的代码区域:

    Public Class Form1
    Dim taskCompleted As Boolean = False
    Dim taskIsrunning As Boolean = False
    
    Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Threading.Thread.Sleep(5000)
    End Sub
    
    
    
    
    
    
    Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        taskCompleted = True
        taskIsRunning = False
        Label1.Text = "Background task completed."
        Me.Close()
    End Sub
    
    
    
    
    
    
    Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If taskIsRunning Then
           e.Cancel = True
           Exit Sub
        End If
    
        If Not taskCompleted Then
            taskIsRunning = True
            Label1.Text = "Starting background task."
            BackgroundWorker1.RunWorkerAsync()
            Label1.Text = "Background task is running."
            e.Cancel = True
        End If
    End Sub
    End Class
    

    【讨论】:

    • 哈哈...我不得不对后台工作人员进行一些阅读...但是感谢您的回答,看来我明白了。谢谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 2021-06-01
    • 2011-04-19
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    相关资源
    最近更新 更多