【发布时间】:2019-07-30 23:54:50
【问题描述】:
我有一个通过调用外部服务进行日志记录的进程。由于所涉及的开销(很小,但会为许多日志消息建立起来),我的进程以“即发即弃”的方式异步记录。我不想等待每条日志消息都通过后再继续,也不想因为记录器出现问题而使我的流程失败。
为了实现这一点,我将主日志调用封装在一个任务中——每次对日志记录的调用都会触发一个任务,该任务就会停止并完成它的工作。大多数时候,我的进程循环遍历需要检查的内容,处理它们,然后正常退出,一路记录。然而,在它发现只有一个项目要处理的情况下,进程完成得如此之快以至于进程退出,从而在日志记录实际发生之前杀死它的所有线程,而我在日志中几乎没有得到任何信息。
我已经确认这是正在发生的事情,方法是检查项目是否按预期处理,即使它们没有记录(它们是),并在记录方法(在任务),以便日志记录确实阻塞。在这种情况下,一切都按预期记录。
(基于此,我实际上相信即使该过程按预期工作,我们也可能会在每次运行结束时丢失几个日志条目,因为它在最后一个条目可以通过之前退出,但我无法确定。)
我可以在过程的最后放置一个延迟,这样无论如何,它至少会挂起一两秒,让这些“一劳永逸”的任务有时间完成,但这感觉很笨拙。
我正在考虑的另一个选项是创建一个日志记录任务的全局列表,该列表将在创建任务时收集它们,以便我可以对它们执行 Task.WaitAll()。这感觉有点像我不应该处理的开销,但它可能是最好的解决方案。
我正在寻找的是某种方式,在我的流程结束时,执行 WaitAll() 类型的调用,不需要我知道我在等待什么任务 - 只需等待任何和所有任务仍然挂在那里(当然,除了进程的主线程)。
这样的事情是否存在,还是我只需要在全球范围内跟踪我的所有任务?
【问题讨论】:
-
stackoverflow.com/questions/47453915/… 这确实需要您参考您的任务。您可能需要重新考虑您的问题
-
请注意,“任务”不是“线程”的同义词。虽然可以将任务分配给线程,但它也可以同步运行。
-
您需要自己跟踪它们。毕竟,您不希望意外等待由不相关的代码创建的真正一劳永逸的任务。例如
var discardedTask = Task.Delay(TimeSpan.FromDays(999));或者更糟的是,抢别人的任务并重新配置它! -
@RaymondChen 好吧,从技术上讲,我也想等待由随机代码创建的任务——如果我不这样做,它们将在进程结束时被杀死。毕竟,这仅涵盖在此过程中创建的任务。 “别人的任务”仍然是在这个过程中创建的任务……
-
追查其他组件创建的任务违反了封装性。在上述情况下,您的应用将在关闭时暂停 999 天。
标签: c# .net multithreading task