2010-06-19 62 views
4

我打电话给Process.Start,但它阻塞当前线程。Process.Start阻塞

pInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe"); 

// Start process 
mProcess = new Process(); 
mProcess.StartInfo = pInfo; 
if (mProcess.Start() == false) { 
    Trace.TraceError("Unable to run process {0}."); 
} 

即使进程关闭,代码也不再响应。

但Process.Start真的应该阻止?这是怎么回事?

(这个过程正常启动)


using System; 
using System.Diagnostics; 
using System.Threading; 
using System.Windows.Forms; 

namespace Test 
{ 
    class Test 
    { 
     [STAThread] 
     public static void Main() 
     { 
      Thread ServerThread = new Thread(AccepterThread); 
      ServerThread.Start(); 

      Console.WriteLine (" --- Press ENTER to stop service ---"); 
      while (Console.Read() < 0) { Application.DoEvents(); } 

      Console.WriteLine("Done."); 
     } 

     public static void AccepterThread(object data) 
     { 
      bool accepted = false; 

      while (true) { 
       if (accepted == false) { 
        Thread hThread = new Thread(HandlerThread); 
        accepted = true; 
        hThread.Start(); 
       } else 
        Thread.Sleep(100); 
      } 
     } 

     public static void HandlerThread(object data) 
     { 
      ProcessStartInfo pInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe"); 

      Console.WriteLine("Starting process."); 

      // Start process 
      Process mProcess = new Process(); 
      mProcess.StartInfo = pInfo; 
      if (mProcess.Start() == false) { 
       Console.WriteLine("Unable to run process."); 
      } 
      Console.WriteLine("Still living..."); 
     } 
    } 
} 

控制台输出为:

---按ENTER键停止服务--- 启动过程。


发现:

[STAThread]

使的Process.Start阻塞。我读了STAThread and Multithreading,但我无法将这些概念与Process.Start行为联系起来。

AFAIK,STAThread是必需由Windows.Form。如何在使用Windows.Form时解决此问题?


新闻为地狱:

如果我重建我的应用程序时,第一一次正确运行的应用程序的工作,但如果我停止调试并重新启动IY,问题araise。

在没有调试器的情况下执行应用程序时,不会引发问题。

+0

将'UseShellExecute'和'ErrorDialog'设置为true,看看是否有错误产生。 – AMissico 2010-06-19 19:34:41

+0

考虑到我们不知道“cDaemon”课程的作用,很难说出发生了什么。请尝试拿出一个简短但完整的*程序来证明问题。 – 2010-06-19 19:36:38

+0

(使用Application.DoEvents结合Console.Read看起来很可疑) – 2010-06-19 19:40:02

回答

10

不,Process.Start不会等待子进程完成...否则您将无法使用重定向I/O等功能。

样品控制台应用程序:

using System; 
using System.Diagnostics; 

public class Test 
{ 
    static void Main() 
    { 
     Process p = new Process { 
      StartInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe") 
     }; 
     p.Start(); 
     Console.WriteLine("See, I'm still running"); 
    } 
} 

这将打印“你看,我仍然在运行”与我的箱子没有问题 - 它是什么在你的盒子做什么?

+0

@usr:将更新。 – 2014-08-07 13:04:18

+0

进程开始似乎阻止我的主线程 – 2015-11-01 19:21:46

+0

@CurtisWhite:它确实不正常。我建议你用一个简短但完整的例子来问一个新问题。 – 2015-11-01 19:26:38

6

创建一个ProcessStartInfo并将UseShellExecute设置为false(默认值为true)。您的代码应为:

pInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe"); 
pInfo.UseShellExecute = false; 

// Start process 
mProcess = new Process(); 
mProcess.StartInfo = pInfo; 
if (mProcess.Start() == false) { 
    Trace.TraceError("Unable to run process {0}."); 
} 

我有同样的问题,并启动可执行文件直接从可执行文件创建过程解决了问题。

+0

+1 - 尽管对我来说,我打开的Excel工作簿阻塞了线程。要打开特定工作簿,请使用ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName =“EXCEL.EXE”; startInfo.Arguments = filePath – Adam 2016-04-22 07:17:27

+0

我一直在试图解决这个问题的日子,谢谢 – 2017-01-10 10:24:05

0

我在WinForms应用程序中遇到与原始海报相同的阻止行为,所以我创建了下面的控制台应用程序来简化测试此行为。

Jon Skeet的例子使用记事本,它只需要几毫秒的时间来正常加载,所以一个线程块可能会被忽视。我试图启动Excel,通常需要很长时间。

using System; 
using System.Diagnostics; 
using static System.Console; 
using System.Threading; 

class Program { 

    static void Main(string[] args) { 

     WriteLine("About to start process..."); 

     //Toggle which method is commented out: 

     //StartWithPath(); //Blocking 
     //StartWithInfo(); //Blocking 
     StartInNewThread(); //Not blocking 

     WriteLine("Process started!"); 
     Read(); 
    } 

    static void StartWithPath() { 
     Process.Start(TestPath); 
    } 

    static void StartWithInfo() { 
     var p = new Process { StartInfo = new ProcessStartInfo(TestPath) }; 
     p.Start(); 
    } 

    static void StartInNewThread() { 
     var t = new Thread(() => StartWithPath()); 
     t.Start(); 
    } 

    static string TestPath = 
     Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + 
     "\\test.xlsx"; 
} 

呼吁双方StartWithPathStartWithInfo阻止我在一个控制台应用程序的线程。直到Excel启动画面关闭并且主窗口打开后,我的控制台才显示“Process Started”。

enter image description here

StartInNewThread将立即显示在控制台上两个消息,而Excel的启动画面仍然是开放的。

+0

哎哟...仍然急于解决这个问题。 – Luca 2016-06-15 23:19:37

0

当启动位于不同域(我们有双受信任域)上的网络驱动器上的.bat脚本时,我们遇到了此问题。我运行了一个远程C#调试器,确保足够的Process.Start()被无限期阻止。

交互时在电源外壳重复这个任务,安全对话被弹出:据

enter image description here

作为一种解决方案,this was the direction我们去。做过工作的人修改了域GPO来完成信任。