我正在创建一个vb.net桌面应用程序。该应用程序包括一些异步功能。当用户通过右上角的红色X关闭应用程序时,可能会运行一个或多个这些异步函数。问题是,程序在完成之前终止。我想用#34; Await"在我的电话会这样做,但显然不是。
我找到this thread that talks about using ManualResetEvent,但我无法理解所有内容,特别是因为问题是在控制台应用程序的上下文中,而答案链接的MSDN文档是关于指定线程,不仅仅是使用异步任务。无论如何尝试使用它,我尝试将其添加到我的主要表单中:
Public resetEvent As ManualResetEvent = New ManualResetEvent(False)
在调用其中一个函数后,我立即添加了这个(引用包括调用):
Await activeCount.SerializeAsync(activeCount)
resetEvent.WaitOne()
在我的异步函数本身结束时,在返回Task之前,添加了:
frmMain.resetEvent.Set()
但是,我不认为我正在使用这个权利。无论如何,该程序在完成之前仍然会终止。
在此之前,我认为这样的事情的最佳位置是ApplicationEvents MyApplication_Shutdown
,但我不知道如何知道这样的功能是否仍然在那时运行。
那么在应用程序在这种情况下终止之前,确保所有异步函数完成的最佳方法是什么?
谢谢!
接受答复后的更新:
虽然F0r3v3r-A-N00b的回答有效,但我意识到在某些情况下我需要使用对话框。我无法在后台工作程序中调用它,因为对话框位于GUI线程上,而不是后台线程。我尝试移动东西,所以我先调用对话框,然后让背景工作者和所有这些,但无论出于什么原因,我都无法让它工作。
长话短说,我通过简单地制作我的功能的同步版本来解决它,所以我可以说,如果用户终止程序并且我需要在关闭之前调用任何这些功能,请调用而是同步版本'。这样可行。谢谢!
答案 0 :(得分:1)
试试这个。创建一个新项目。在表单中添加1个标签和backgroundworker。将其粘贴到表单的代码区域中:
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