任务处理上的应用程序关闭(Task Handling on Application Shutdown

2019-07-31 04:42发布

我有一个.net(V4.0)的Windows服务在执行某些,长时间运行的活动一开始就TPL的任务是旋转的应用,基本上保持活着的应用程序的生命周期,因此与TaskCreationOptions创建。 LongRunning参数值。

每当服务被停止,并且.OnStop()方法被调用,我.Cancel()中的CancellationToken(来源)我交给工人任务时,我创造了它,我想它的.OnlyOnCanceled(...)延续任务跑。

问题是,服务/进程关闭而没有后续任务,通过“完全”运行 - 有时它退出相当快,有时它贯穿完全,有时没有。

这有一定道理,以我为特定的任务可能是坐在另一个线程比主之一,因此没有“拖延” /阻断主要的一个结束的方式。

由于我没有在Windows服务应用程序,我不能告诉后续任务在主线程,所以我想知道在那里运行/年的SynchronizationContext:我该怎么

更确切地说,有什么处理与运行TPL任务的应用程序停机的最佳做法

Answer 1:

你必须等待你的任务,在完成OnStop方法(或OnPauseOnShutdown )。

你有20秒左右做任何你需要OnStop 。 如果你不认为你的线程将在20秒内完成吗,你应该叫RequestAdditionalTime 。 只要你从返回OnStop服务过程可以终止。

使用ContinueWith异步调用传递给它的代表,不管你是否通过ExecuteSynchronously或使用SynchronizationContext 。 只要ContinueWith执行,假设这是最后一行OnStopOnStop返回并控制返回到SCN(当然, ServiceBase ,但它设置你的服务的状态停止,控制权返回给SCM到大概终止您的进程。

ExecuteSynchronously意味着延续关于它的持续任务同步运行。 即同一个线程任务(如果可能)上运行。 该任务可能不会被调用线程上运行ContinueWith (否则就不能称之为ContinueWith ),所以ExecuteSynchronusly没有关于呼叫同步意味着ContinueWith

你需要做的是这样的:

RequestAdditionalTime(TimeSpan.FromSeconds(30).Milliseconds);
cancellationToken.Cancel();
task.Wait();

OnStopWait意味着你不会从退出OnStop ,直到你的任务完成(或需要超过30秒,你的进程被终止)



Answer 2:

出现这种情况是因为延续任务也异步运行。 为了它阻止你需要指定任务延续选项 :

...
t.ContinueWith(ct => {...}, TaskContinuationOptions.ExecuteSynchronously);


Answer 3:

指定TaskContinuationOptions.ExecuteSynchronously上延续不影响前因。 如果等待的前因,然后退出服务,您的延续可能仍无法运行!

要做到这一点的唯一方法是等待后续任务从返回之前完成OnStop



Answer 4:

恕我直言,这是一个坏适合使用TPL的。 任务是不是真的意味着这种“永远运行”的逻辑。

IME,这是更简单/更容易启动一个新的线程为这个专门的工作。 由于默认为背景= false时,CLR会自动等待它退出之前完成(服务规则仍然适用)。

添加私人布尔停止; 然后你的线程方法只需要而做的(停止== FALSE){DoStuff(); } DoStoppingStuff(); } DoStoppingStuff();

你调用OnStop那么就设置停止=真,你的线程将退出while循环,做你停止代码:)

IME你不需要添加挥发性,但你肯定能



文章来源: Task Handling on Application Shutdown