2010-06-19 69 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來完成信任。