Windows 我如何等待工作进程完成,但又如何限制它';是时候这么做了?
我正在用VB.Net编写一个Windows服务,它将输出一些设备和数据记录点的信息。我正在使用后台工作人员来完成这项工作,因此服务本身仍然能够响应。我有一个计时器,每秒钟运行一次,检查当前时间的分钟部分。每次分钟组件更改时,我都会检查需要检查的设备,有些是每分钟检查一次,有些是每5分钟检查一次,有些是每10分钟检查一次,等等。这些过程可能需要几秒钟或一分钟以上(我只会在辅助进程尚未运行时重新运行辅助进程,如果最后一个进程的时间长于数据检索间隔时记录错误) 在我为该服务举办的现场活动中,我希望确保所有工人都停工。我在worker上调用CancelAsync,worker检查取消,希望能够干净地退出(即,检查取消,如果为false,则检索数据,将数据保存到数据库中,循环) 我的问题是我不想使用sleep语句,因为它会锁定所有内容,但我也不希望服务永远不会关闭。例如,我现在有:Windows 我如何等待工作进程完成,但又如何限制它';是时候这么做了?,windows,vb.net,service,Windows,Vb.net,Service,我正在用VB.Net编写一个Windows服务,它将输出一些设备和数据记录点的信息。我正在使用后台工作人员来完成这项工作,因此服务本身仍然能够响应。我有一个计时器,每秒钟运行一次,检查当前时间的分钟部分。每次分钟组件更改时,我都会检查需要检查的设备,有些是每分钟检查一次,有些是每5分钟检查一次,有些是每10分钟检查一次,等等。这些过程可能需要几秒钟或一分钟以上(我只会在辅助进程尚未运行时重新运行辅助进程,如果最后一个进程的时间长于数据检索间隔时记录错误) 在我为该服务举办的现场活动中,我希望确保
Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop your service.
My.Application.Log.WriteEntry("ServiceABC shutting down for device " & DeviceID)
ServiceTimer.enable = false
If DataRetrievalBackgroundWorker.IsBusy Then
DataRetrievalBackgroundWorker.CancelAsync()
Dim x As Integer = 0
While ((DataRetrievalBackgroundWorker.IsBusy) Or (x < 15))
Threading.Thread.Sleep(1000)
x += 1
End While
End If
End Sub
protectedoverrides子桌面()
'在此处添加代码以执行停止服务所需的任何拆卸。
My.Application.Log.WriteEntry(“为设备关闭ServiceC”&DeviceID)
ServiceTimer.enable=false
如果DataRetrievalBackgroundWorker.IsBusy,则
DataRetrievalBackgroundWorker.CancelAsync()
尺寸x为整数=0
While((DataRetrievalBackgroundWorker.IsBusy)或(x<15))
线程。线程。睡眠(1000)
x+=1
结束时
如果结束
端接头
因为后台工作线程位于另一个线程上,所以应该可以这样做,对吗?有没有更好的方法来处理这个问题?你很接近了,如果你不想睡觉(1000)并把东西锁起来,那就睡一觉(1)
'尺寸x为整数=0
'而((DataRetrievalBackgroundWorker.IsBusy)或(x<15))
'线程。线程。睡眠(1000)
'x+=1
"结束!
Dim T As Date=Now.ADDSECONES(15)
当DataRetrievalBackgroundWorker.IsBusy或Now()时
线程。线程。睡眠(1)
Application.DoEvents()
结束时
使用任务而不是BackGroundWorker,等待它,传递带有超时设置的CancellationToken及其CancellationTokenSource。ReportProgress
过程被替换为传递几乎相同的Progress
委托并调用其Report()
方法。如果需要,可以在Task
的T
对象中返回完成结果。我以前从未使用过任务,但我会看看我能找到什么。这里有一些不同的示例:。了解当前在DoWork
处理程序中执行的操作类型、是否调用ReportProgress()
以及BGW终止时使用的数据和发生的情况(即,如果在RunWorkerCompleted
中执行其他操作),这一点非常重要。一般来说,如果您正在执行IO绑定工作或CPU绑定工作,那么当前的BGW将转到URL,获取数据,并将其插入SQL数据库。它在一个广泛的URL列表中循环,有时可达2k,但检索到的数据很小(20个字符左右)。它目前不支持ReportProgress
,RunWorkerCompleted
中唯一的一个变量是一个用日期更新的last run变量。现在,我可以跟踪它运行的时间。因此,IO绑定,它也支持异步/等待模式,因为您有所有可等待的方法。不清楚您正在使用下载的数据做什么。只需更新数据库,全部在DoWork
处理程序中?数据库更新也是(通常)可等待的(例如,SqlCommand.ExecuteReaderAsync()
,SqlCommand.ExecuteNonQueryAsync(()
等),并且具有接受CancellationToken的重载(因此,隐式地,也是一个超时,因为这是由创建CancellationToken的CancellationTokenSource设置的)是的,我想我也可以这样做。真正的问题是,如果我在实际工作中使用背景工作人员,这是否重要……睡眠(1000次)“不应该”阻止它完成,因为它是在自己的线程上,对吗?另一个选项是查看@Jimi发布的任务,我仍在试图弄清楚。我忘记添加DoEvents…是的,后台工作人员无论如何都不会被阻止。我不喜欢任务,一旦你执行任务,你就不能返回。我可以将sub转换为线程并调用它不管怎样,我想。你不能用任务来做。一旦子任务是一项任务,它就只是一项任务。
'Dim x As Integer = 0
'While ((DataRetrievalBackgroundWorker.IsBusy) Or (x < 15))
' Threading.Thread.Sleep(1000)
' x += 1
'End While
Dim T As Date = Now.AddSeconds(15)
While DataRetrievalBackgroundWorker.IsBusy Or Now() < T
Threading.Thread.Sleep(1)
Application.DoEvents()
End While