以安全的方式在企业应用程序中运行multipe Task <>

菲利斯·波拉诺(Felice Pollano)

我正在为产品设计软件体系结构,该产品可以实例化一系列“代理”来做一些有用的事情。假设每个代理实现一个具有功能的接口:

Task AsyncRun(CancellationToken token)

因为由于这些代理执行大量I / O,所以将其作为async功能可能会有些道理此外,如果没有异常或明确的取消事件发生,则认为AsyncRun永远不会完成。

现在的问题是:主程序必须在多个代理上运行它,我想知道运行多个任务的正确方法,用信号通知每个完成(由于取消/错误):例如,我在考虑像这样无限循环

//.... all task cretaed are in the array tasks..
while(true)
{
     await Task.WhenAny(tasks)
     //.... check each single task for understand which one(s) exited
     // re-run the task if requested replacing in the array tasks
}

但是我不确定这是否是正确的(甚至是最好的方法),而且我想知道这是否是正确的模式,尤其是因为实现者可能会不匹配RunAsync并执行阻塞调用,在这种情况下,整个应用程序将挂起。

斯蒂芬·克莱里

//如果需要替换数组任务,请重新运行该任务

这是我要考虑改变的第一件事。最好不要让应用程序处理自己的“重新启动”。如果操作失败,则无法保证应用程序可以恢复。对于任何语言/运行时的任何类型的操作都是如此。

更好的解决方案是让另一个应用程序重新启动该应用程序。允许传播该异常(如果可能,请记录该异常),并允许它终止应用程序。然后,根据需要重新启动“经理”过程(实际上是一个单独的可执行过程)。从Win32服务管理器到ASP.NET,再到Kubernetes容器管理器,再到Azure Functions运行时,所有现代高可用性系统都是这样工作的。

请注意,如果您确实希望采用这种方式,则可以将任务拆分为不同的进程,这样就可以独立地重新启动它们。这样一来,重启不会导致其他用户重启。

但是,如果您希望将所有任务保持在同一流程中,那么您拥有的解决方案就可以了。如果您在流程开始时拥有已知数量的任务,并且该数目不会改变(除非它们失败),那么您可以通过考虑重新启动并使用Task.WhenAll代替来简化代码Task.WhenAny

async Task RunAsync(Func<CancellationToken, Task> work, CancellationToken token)
{
  while (true)
  {
    try { await work(token); }
    catch
    {
      // log...
    }

    if (we-should-not-restart)
      break;
  }
}

List<Func<CancellationToken, Task>> workToDo = ...;
var tasks = workToDo.Select(work => RunAsync(work, token));
await Task.WhenAll(tasks);
// Only gets here if they all complete/fail and were not restarted.

实现者可能会与RunAsync不匹配并进行阻塞调用,在这种情况下,整个应用程序将挂起。

防止这种情况的最佳方法是将呼叫包装在中Task.Run,因此:

await work(token);

变成这个:

await Task.Run(() => work(token));

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在不使用 Task.Run() 的 Windows 窗体应用程序中的异步任务中改变 DataTable 是否安全?

ClickOnce应用程序无法从Task Scheduler执行

在Task#onSucceeded中调用Task#get安全吗?

在ASP.NET Web应用程序中对Task使用async / await时,UI线程被阻止

如何从控制台应用程序中的Task.WaitAll()获得返回值?

在ASP .NET MVC Web应用程序中,Task.Run是否被视为不良做法?

Task.IsFaulted 在我的 .Net 核心应用程序中不起作用

对于KDE Task Manager中的固定应用程序,仅显示不带标签的图标

ThreadLocal在企业应用程序中的用法

Windows Scheduled Task拒绝运行

循环运行Task引发ArgumentOutOfRangeException

C#如何防止Task与正在运行的Task冲突?

在Task.Run中动态

Unity中“运行应用程序”的快捷方式

MySQL - 错误代码:1054。“on 子句”中的未知列“task_log_wip.task_log_task”

苹果应用程序传输安全(ATS)的企业应用程序

Windows Task Manager:Python应用程序内存使用量增加

如何防止应用程序在Windows Task Manager中被杀死?

Windows 10 Task Scheduler将在指定的时间后在空闲状态下启动应用程序

如何在 WPF 应用程序中将 System.Threading.Tasks.Task<double> 显示为标签?

如何显示Windows Task Scheduler启动的命令行应用程序?

在PCL中使用Task时C#应用程序掉落

在ASP.Net应用程序中使用Task.WhenAny()的性能影响

如何保护App Engine应用程序仅对Google Cloud Task可用?

无法为参考BCL的Web应用程序序列化Task`1。

以FLAG_ACTIVITY_NEW_TASK启动之后,关闭Android应用程序

从返回 Task.FromResult(...) 的方法中读取 Task.Result 属性是否安全?

禁用应用程序运行-安全警告

iOS企业版应用程序-如何确保我的应用程序在后台运行?