应用程序关闭时的任务处理 [英] Task Handling on Application Shutdown
问题描述
我有一个.Net(v4.0)Windows Service应用程序,该应用程序在开始时旋转tpl任务,该任务执行某些长时间运行的活动,并在应用程序的生命周期内基本保持活动状态,因此是使用TaskCreationOptions创建的. LongRunning 参数值.
每当服务停止并调用.OnStop()方法时,我 .Cancel() CancellationToken(Source)我在创建它并希望将它移交给worker任务时 .OnlyOnCanceled(...)继续任务要运行.
问题是,服务/进程关闭而没有继续执行任务的整个"操作-有时退出非常快,有时完全运行,有时没有.
这对我来说确实有意义,因为该特定任务可能位于主线程之外的另一线程上,因此无法跟踪"/阻止该主线程结束.
由于我在Windows服务应用程序中没有SynchronizationContext,所以我无法告诉该继续任务在主线程中/在主线程上运行,所以我想知道:我将如何 这样做? /p>
更准确地说,通过运行tpl任务来处理应用程序关闭的最佳实践是什么?
您必须等待OnStop
方法(或OnPause
和OnShutdown
)中的任务完成.
您有大约20秒的时间完成OnStop
中需要执行的任何操作.如果您认为线程不会在20秒内完成,则应调用RequestAdditionalTime
.从OnStop
返回后,您的服务过程便会终止.
使用ContinueWith
将异步调用传递给它的委托,而不管您是通过ExecuteSynchronously
还是使用SynchronizationContext
.一旦执行ContinueWith
,假定这是OnStop
的最后一行,OnStop
返回并将控制权返回给SCN(好吧,ServiceBase
,但是它将服务的状态设置为STOPPED并将控制权返回给SCM大概终止您的过程.
ExecuteSynchronously
表示延续相对于其继续执行的任务是同步运行的.即在与任务相同的线程上运行(如果可能).该任务可能 not 在正在调用ContinueWith
的线程上运行(否则它无法调用ContinueWith
),因此ExecuteSynchronusly
并不意味着对
您需要执行以下操作:
RequestAdditionalTime(TimeSpan.FromSeconds(30).Milliseconds);
cancellationToken.Cancel();
task.Wait();
在OnStop
中,Wait
表示您直到任务完成(或者花费30秒以上的时间并且您的进程被终止)后才会从OnStop
退出
I have a .Net (v4.0) Windows Service Application that spins of a tpl task at the beginning that performs certain, long running activities and basically stays alive for the application's life time and as such is created with the TaskCreationOptions.LongRunning parameter value.
Whenever the service is stopped and the .OnStop() method is called, I .Cancel() the CancellationToken(Source) I handed over to the worker task when I created it and I want it's .OnlyOnCanceled(...) continuation task to run.
The thing is, the service/process shuts down without that continuation task to run through "entirely" - sometimes it quits rather quickly, sometimes it runs through completely, sometimes it doesn't.
This does make sense to me as that particular task is probably sitting on another thread than the main one and thereby has no way of "stalling"/blocking that main one to end.
As I do not have a SynchronizationContext in that windows service application I can't tell that continuation task to run there/on the main thread so I was wondering: how would I do that?
And more precisely, what's the best practice to handle an application shutdown with running tpl tasks?
You'll have to wait for your task to complete in the OnStop
method (or OnPause
and OnShutdown
).
You have about 20 seconds to do whatever you need in OnStop
. If you don't think your thread will complete in 20 seconds, you should call RequestAdditionalTime
. As soon as you return from OnStop
your service process can be terminated.
Using ContinueWith
will asynchronously invoke the delegate passed to it, regardless of whether you pass ExecuteSynchronously
or use a SynchronizationContext
. As soon as the ContinueWith
executes, assuming that's the last line of OnStop
, OnStop
return and returns control to the SCN (well, ServiceBase
, but it sets your service's state to STOPPED and returns control to the SCM to presumably terminate your process.
ExecuteSynchronously
means that the continuation runs synchronously with regard to the task it's continuing from. i.e. run on the same thread as the task (if possible). The task is likely not running on the thread that is calling ContinueWith
(otherwise it couldn't call ContinueWith
) so ExecuteSynchronusly
doesn't mean synchronously with regard to the call to ContinueWith
.
You need to do something like:
RequestAdditionalTime(TimeSpan.FromSeconds(30).Milliseconds);
cancellationToken.Cancel();
task.Wait();
in OnStop
, the Wait
means you won't exit from OnStop
until your task completes (or it takes longer than 30 seconds and your process gets terminated)
这篇关于应用程序关闭时的任务处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!