COM 线程的看门狗

发布于 2024-12-09 02:37:53 字数 882 浏览 0 评论 0原文

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

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

这一切都很好,但是为了执行从“启动进程”返回,我使用

oThread = new Thread(new ThreadStart(wbrt.Calculate));< 在单独的线程中运行我的代码/code>

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

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

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

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

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

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

另外,我正在使用 Activator.CreateInstance 创建 COM 对象,我尝试中止线程,但它不会杀死 COM 对象,而且我已经了解到中止是不好的。

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

任何想法都受到好评!

i am developing a WCF application that does not adhere to the idea world of a true SOA in that it will have a few basic calls.

1) Start Process
2) Check if process is still running
3) Get results

This is all fine, but in order for execution to return from the 'start process' I am running my code in a separate thread using

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

The problem is it has been known (though rare) for the COM call to hog and sit at 50~100% cpu and consume lots of memory. There is nothing I can do to prevent this.

What I want to do is have a watchdog thread that will kill off the COM call if it is still running after some time (say 5 minutes).

Is there a best practice here? I have been reading the following blog:

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

in which he makes use of 'AutoResetEvent' and 'WaitOne' problem here is WaitOne is blocking so I'd have to have a thread within a thread.

Could I use a simple Thread Timer here? I saw that the timer will execute even if the thread has closed (i.e. finished ok) is that a problem if I use a flag or something to stop use of now dead objects?

Also I am creating my COM object using Activator.CreateInstance I tried Aborting the thread, but it does not kill the COM object and I have since read that Abort is bad.

My solution is to get the PID of the COM instance and simply kill, working on the assumption that if the timeout has hit diplomacy with the thread has gone out of the window.

Any thoughts well received!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

抱猫软卧 2024-12-16 02:37:53

最简单的方法是使用一个 ManualResetEvent 调用带有超时值的 WaitAny()。

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();
}

Easiest way to do this is one ManualResetEvent with calling WaitAny() with a timeout value.

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文