繁体   English   中英

为什么即使我在单独的线程中,Process.WaitForExit也会阻止?

[英]Why does Process.WaitForExit block even though I have it in a separate thread?

C#3.5 Winforms应用程序。

我有一个计时器,该计时器在单独的线程上每30秒触发一次(它所做的只是向VS输出窗口写入文本字符串)。

我也有另一个线程,如果它启动,它会等待某个进程结束。 例如winword.exe。

在那个线程中,我有以下代码:

p.WaitForExit();

它将坐在那里,等待winword.exe退出。 很好

但是,当它坐在那里等待winword.exe退出时,一个完全独立的线程(将文本发送到输出窗口)上的30秒计时器永远不会运行。

如果我等待3分钟(因此另一个计时器应该在此时运行6次,但是在WaitForExit()等待时不会),然后退出winword.exe 突然我的另一个计时器立即开始运行6次。 就像计时器事件积压了一样,.Net突然想同时运行所有事件。

为什么p.WaitForExit()似乎阻止了我的整个应用程序,即使我是从应用程序中的单独线程(而不是主UI线程)执行它的呢?

编辑:是的,它在单独的线程中。 这是我用来启动它的代码:

        try
        {
            Thread t = new Thread(ProcessCheck); // Kick off a new thread
            t.Start();

            ConfigLogger.Instance.LogInfo("++ ProcessCheck thread started @ " + DateTime.Now);
        }
        catch (Exception ipwse)
        {
            ConfigLogger.Instance.LogInfo(ipwse.Message + " " + ipwse.StackTrace);
        }



这是我拥有的ProcessCheck()方法:

foreach (Process p in System.Diagnostics.Process.GetProcessesByName("winword"))
{
    this.Invoke(new MethodInvoker(delegate()
    {                                                                                 
        try
        {
            p.WaitForExit();
        }
        catch (Exception)
        {

        }
    }));
}

如果从WinForms表单完成,则this.Invoke将阻塞UI线程,直到进程退出。 如果Timer为System.Windows.Forms.Timer,则在UI线程上引发Tick事件。 如果UI线程被阻止,那将解释为什么Tick事件永远不会引发。

我不确定,因为以下程序表明只要您正确执行线程操作,您所做的工作就可以正常工作。

static void Main(string[] args)
{
    BackgroundWorker shortThread = new BackgroundWorker(), waitThread = new BackgroundWorker();

    shortThread.WorkerSupportsCancellation = true;
    shortThread.DoWork += (s, e) =>
        {
            while (true)
            {
                if (shortThread.CancellationPending)
                {
                    break;
                }

                Console.WriteLine("Hello World...");
                Thread.Sleep(2000);
            }
        };

    waitThread.WorkerSupportsCancellation = true;
    waitThread.DoWork += (s, e) => { Process.Start("winword.exe").WaitForExit(); };

    shortThread.RunWorkerAsync();
    waitThread.RunWorkerAsync();

    Console.ReadLine();

    shortThread.CancelAsync();
    waitThread.CancelAsync();
}

因此,在我看来,您是在主线程而不是单独的线程上发布WaitForExit()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM