【问题标题】:Multi-Threading - Cleanup strategy at program end多线程 - 程序结束时的清理策略
【发布时间】:2023-03-14 01:40:02
【问题描述】:

以干净的方式完成多线程应用程序的最佳方法是什么?
我正在从单独的套接字中的主线程开始几个套接字连接,并在主线程中等到我的工作日结束,并使用当前System.Environment.Exit(0) 来终止它。

这会导致其中一个孩子出现未处理的异常。我应该停止列表中的线程吗?我一直不愿意在孩子身上实施任何真正的停止,因此我想知道最佳实践。套接字都用适当的析构函数很好地包装了注销和关闭,但它仍然会导致错误。

【问题讨论】:

    标签: c# multithreading termination


    【解决方案1】:

    看看 jon skeet 关于多线程的文章:

    http://www.yoda.arachsys.com/csharp/threads/

    尤其是“优雅地关闭工作线程”:

    http://www.yoda.arachsys.com/csharp/threads/shutdown.shtml

    【讨论】:

    • 非常非常好的资源。还可以查看albahari.com/threading 以获得对许多线程概念的清晰理解。
    【解决方案2】:

    对于手动创建的线程,您应该将 IsBackground 属性设置为 true。在这种情况下(如果除主线程之外的所有线程)都是后台线程,您的应用程序在从 Main(string[] arg) 函数返回后优雅地关闭。

    附:所有线程池线程都是后台的。

    【讨论】:

    • 让所有工作线程成为后台线程可以避免进程退出时的任何死亡呼喊,但这并不优雅。一旦所有前台线程都结束,后台线程也会终止,即使它们正在做某事。
    • 我已经实现了这个,我会在星期一测试它。
    • 我会说这是不好的做法。它在某些情况下有效,但在其他情况下您会丢失重要数据。
    【解决方案3】:

    每当您进行长时间阻塞等待(例如等待传入连接)时,请使用该方法的 Begin/End 形式。然后使用 ManualResetEvent 来表示“应该退出”条件。然后阻塞 AsyncWaitHandle 和退出事件。这将允许您干净地终止。

    例子:

    // exit is a ManualResetEvent
    var asyncResult = socket.BeginAccept(null, null);
    if(WaitHandle.WaitAny(new[] { exit, asyncResult.AsyncWaitHandle }) == 0)
       return;
    var connection = socket.EndAccept(asyncResult);
    

    当你想退出时,在你的主要方法中:

    exit.Set();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      • 2011-02-03
      相关资源
      最近更新 更多