2011-12-30 50 views
0

在多線程應用程序中啓動新進程時,是否有任何問題需要謹慎處理?爲什麼線程在啓動新進程時停止,而應用程序(c#)仍在運行?

我在一個簡單的項目嘗試這樣做:

static void Main(string[] args) 
{ 
    Process.Start(@"D:\System\Desktop\a.txt"); 
    MessageBox.Show("Success"); 
} 

,它運行完美。但是當我在我的大項目中使用多線程的時候,線程停止工作(「a.txt」打開,但「成功」未顯示),而我的應用程序(其他線程)則做得很好。

這種情況下的問題是什麼?

+0

你可以試試Console.Writeline(「Success」);相反,看看是否有用? – neeKo 2011-12-30 06:18:49

+0

我試過了。同樣的結果!啓動該進程後,該線程中的所有內容都將停止! – 2011-12-30 06:51:55

+0

嗯,我無法重現這一點...我做了一個線程,打開一個進程,並將消息放入控制檯,它的工作原理應該...您還在做什麼?您可以嘗試在process.start之前放置一個斷點,然後逐步檢查它是否真的停止(因爲它不應該) – neeKo 2011-12-30 07:01:50

回答

2

如果您有Windows.Forms應用程序,並且您嘗試從不是主用戶界面線程的線程顯示消息框,則消息框的行爲是未定義的。意思是,它可能會或可能不會顯示,不一致或其他問題。

例如,從BackgroundWorker的DoWork事件中顯示消息框可能會或可能不起作用。在一種情況下,無論點擊哪個按鈕,消息框結果總是取消。

因此,如果您只是爲了調試目的而使用消息框,請使用其他技術。如果必須顯示消息框,請從主用戶界面線程調用它。

控制檯應用程序通常不應該有顯示消息框的問題。然而,我曾經遇到過在消息框通話之前我不得不睡100ms的情況。

請注意,正如TomTom指出的,主要的用戶界面線程是應用程序的Windows消息循環。這提醒了我,我曾經在控制檯應用程序中創建一個表單以創建Windows消息循環,因此我的應用程序可以響應Windows消息。

+0

解決的問題,如果出現問題或缺少windows消息循環。 – TomTom 2011-12-30 08:26:45

+0

@TomTom;這是我不記得的,Windows消息循環。謝謝。 – AMissico 2011-12-30 08:35:27

+0

我的問題是不顯示消息框,它只是爲了檢查。 (...) – 2011-12-30 12:38:15

0

確保Process.Start有效。在某些情況下傳遞文件名不夠好。在你的示例代碼中,你將不得不設置use-shell屬性;否則,你將不得不使用cmd start <filename>或同等學歷。

因此,只需啓動NotePad.exe以確保Process.Start有效。如果這樣做,那麼你的問題是進程命令和命令行。

+0

同樣的問題:'Process ptemp = new Process(); ptemp.StartInfo.FileName =「Notepad.exe」; ptemp.StartInfo.WindowStyle = ProcessWindowStyle.Maximized; ptemp.StartInfo.CreateNoWindow = false; ptemp.StartInfo.UseShellExecute = true; ptemp.Start(); 返回「成功」;'斷點停在'ptemp.Start();'並且不會繼續運行以返回成功字符串。 – 2011-12-30 13:12:57

2

這是沒有答案 - 我不能把所有這些代碼在評論...

這對我的作品。告訴我你的代碼從這個的區別:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Diagnostics; 
using System.Threading; 
using System.IO; 

namespace Test 
{ 
    class Program 
    { 
     const string OutputFile = @"E:\Output.txt"; 

     object _lock = new object(); 

     static void Main(string[] args) 
     { 
      Program program = new Program(); 

      Thread thread = new Thread(program.ThreadMethod); 
      thread.Start(@"E:\Test.txt"); 

      thread = new Thread(program.ThreadMethod); 
      thread.Start(@"E:\DoesntExist.txt"); 

      Console.ReadKey(); 
     } 

     void ThreadMethod(object filename) 
     { 
      String result = RunNormal(filename as string); 
      lock (_lock) 
      { 
       FileInfo fi = new FileInfo(OutputFile); 
       if (!fi.Exists) 
       { 
        try 
        { 
         fi.Create().Close(); 
        } 
        catch (System.Security.SecurityException secEx) 
        { 
         Console.WriteLine("An exception has occured: {0}", secEx.Message); 
         return; 
        } 
       } 

       StreamWriter sw = fi.AppendText(); 
       sw.WriteLine(result); 
       sw.Close(); 
      } 
     } 

     string RunNormal(string fullfilename) 
     { 
      try 
      { 
       Process.Start(fullfilename); 
       return fullfilename + "|Success"; 
      } 
      catch (Exception e) 
      { 
       return fullfilename + "|" + e.ToString(); 
      } 
     } 
    } 
} 

在Output.txt的輸出是:

E:\DoesntExist.txt|System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified 
    at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo) 
    at System.Diagnostics.Process.Start() 
    at System.Diagnostics.Process.Start(ProcessStartInfo startInfo) 
    at System.Diagnostics.Process.Start(String fileName) 
    at Test.Program.RunNormal(String fullfilename) in E:\Projekti\VS2010\Test\Test\Program.cs:line 59 
E:\Test.txt|Success 

多少不同的是你的代碼?你打電話給其他方法嗎?你如何處理結果?

+0

+1;不錯的代碼。我喜歡鎖的用戶,FileInfo和try ... catch塊。 – AMissico 2011-12-30 08:47:21

+0

是的,在新項目中它也適用於我。但是在我的大項目中,它並沒有。這和我上面的功能一樣 – 2011-12-30 13:07:12

相關問題