[英]Process.Start is blocking
我正在調用 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 停止服務 --- 啟動進程。
找到了:
[STA線程]
使 Process.Start 阻塞。 我閱讀了STAThread 和 Multithreading ,但我無法將這些概念與 Process.Start 行為聯系起來。
AFAIK,Windows.Form需要STAThread。 使用 Windows.Form 時如何解決此問題?
地獄新聞:
如果我重建我的應用程序,我第一次運行應用程序工作正常,但如果我停止調試並再次重新啟動,問題就會出現。
在沒有調試器的情況下執行應用程序時不會出現問題。
不, 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");
}
}
這會在我的盒子上打印“看,我還在跑步”,而我的盒子沒有問題 - 它在你的盒子上做了什么?
創建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}.");
}
我遇到了同樣的問題,直接從可執行文件創建進程啟動可執行文件解決了這個問題。
我在 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";
}
對StartWithPath
和StartWithInfo
的調用會阻止我在控制台應用程序中的線程。 在 Excel 初始屏幕關閉且主窗口打開之前,我的控制台不會顯示“進程已啟動”。
StartInNewThread
將立即在控制台上顯示這兩條消息,而 Excel 的初始屏幕仍處於打開狀態。
我們在啟動位於不同域的網絡驅動器上的 .bat 腳本時遇到了這個問題(我們有兩個受信任的域)。 我運行了一個遠程 C# 調試器,果然 Process.Start() 無限期地阻塞了。
在 power shell 中以交互方式重復此任務時,會彈出一個安全對話框:
就解決方案而言, 這是我們前進的方向。 完成工作的人修改了域 GPO 以完成信任。
通過命令提示符啟動服務器:
"C:\Program Files (x86)\IIS Express\iisexpress" /path:\Publish /port:8080
這可以訪問操作系統樹進程的子線程。
如果要啟動進程,然后使進程獨立於“啟動器”/發起調用:
//Calling process
using (System.Diagnostics.Process ps = new System.Diagnostics.Process())
{
try
{
ps.StartInfo.WorkingDirectory = @"C:\Apps";
ps.StartInfo.FileName = @"C:\Program Files\Microsoft Office\Office14\MSACCESS.EXE"; //command
ps.StartInfo.Arguments = @"C:\Apps\xyz.accdb"; //argument
ps.StartInfo.UseShellExecute = false;
ps.StartInfo.RedirectStandardOutput = false;
ps.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized;
ps.StartInfo.CreateNoWindow = false; //display a windows
ps.Start();
}
catch (Exception ex)
{
MessageBox.Show(string.Format("==> Process error <=={0}" + ex.ToString(), Environment.NewLine));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.