【问题标题】:Watchdog for COM ThreadCOM 线程的看门狗
【发布时间】:2011-12-04 15:26:32
【问题描述】:

我正在开发一个 WCF 应用程序,它不符合真正 SOA 的理念世界,因为它将有一些基本调用。

1) 启动过程 2)检查进程是否仍在运行 3) 获取结果

这一切都很好,但为了让执行从“启动进程”返回,我正在使用的单独线程中运行我的代码

oThread = new Thread(new ThreadStart(wbrt.Calculate));

问题是众所周知(尽管很少见)COM 调用会占用 50~100% cpu 并消耗大量内存。我无法阻止这种情况发生。

我想做的是有一个看门狗线程,如果 COM 调用在一段时间后(比如 5 分钟)仍在运行,它将终止它。

这里有最佳实践吗?我一直在阅读以下博客:

http://weblogs.asp.net/israelio/archive/2004/06/19/159985.aspx

他在这里使用“AutoResetEvent”和“WaitOne”的问题是 WaitOne 正在阻塞,所以我必须在一个线程中有一个线程。

我可以在这里使用一个简单的线程计时器吗?我看到即使线程已关闭(即完成正常),计时器也会执行,如果我使用标志或其他东西来停止使用现在已死的对象,那会不会有问题?

此外,我正在使用 Activator.CreateInstance 创建我的 COM 对象,我尝试中止线程,但它并没有杀死 COM 对象,并且我从那以后读到 Abort 很糟糕。

我的解决方案是获取 COM 实例的 PID 并简单地终止,假设如果超时已命中外交,则线程已超出窗口。

任何想法都受到好评!

【问题讨论】:

  • 您必须在自己的进程中托管此 COM 对象,才能有机会从中止中恢复。
  • 嗨,实例化 COM 的调用在它自己的线程中,然后这会启动对注册并在自己的进程中运行的 ole 服务器的调用。
  • 如果调用卡住,完全占用资源和内存,在不知道其内部机制的情况下启动它的方法是终止线程。然而,这个想法真的很疯狂,因为这并不能有效地保证这个手术是准确的(同步对象可能处于锁定状态,其他线程正在运行等),所以你最好把调用放在单独的进程上上面的汉斯建议。在这种情况下,终止进程将强制清理资源,并且您的父应用程序将优雅地解除锁定,使用 HRESULT 而不是未释放的锁定。

标签: c# .net multithreading com


【解决方案1】:

执行此操作的最简单方法是使用具有超时值调用 WaitAny() 的 ManualResetEvent。

ManualResetEvent _evtActor = new ManualResetEvent();

public void Start()
{
    this._evtActor.Reset();

    ThreadPool.QueueUserWorkItem(new WaitCallback(DoStuff));

    int result = ManualResetEvent.WaitAny(
                    new WaitHandle[] { this._evtActor },
                    30 * 1000); // Wait 30sec

    if (result == ManualResetEvent.WaitTimeout)
    {
        Console.WriteLine("Timeout occurred!");
    }
    else
    {
        Console.WriteLine("Done!");
    }
}

public void DoStuff()
{
    Console.WriteLine("Doing stuff.");
    Thread.Sleep(45 * 1000); // sleep for 45sec;
    this._evtActor.Set();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-19
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    相关资源
    最近更新 更多