2011-11-04 135 views
27

我正在尋找一種在新線程上調用方法的方法(使用C#)。例如,我想在一個新的線程上調用SecondFoo()。但是,我想然後在SecondFoo()完成時終止該線程。C#在新線程中調用方法

我已經在C#中看到了幾個線程的例子,但沒有一個適用於這個特定場景;我需要產生的線程來終止它自己。這可能嗎?

如何強制運行Secondfoo()的衍生線程在完成時終止?

有沒有人遇到過這個的任何例子?

非常感謝, 佈雷特

+3

當Secondfoo()返回時,它所運行的線程將終止。你爲什麼認爲它不? –

+0

有什麼理由不能使用ThreadPool? –

回答

61

如果你真正開始一個新的線程,該線程結束時方法完成:

Thread thread = new Thread(SecondFoo); 
thread.Start(); 

現在SecondFoo將在新的線程中調用,該線程完成時會終止。

您是否確實表示您希望線程在調用線程完成時終止?

編輯:請注意,啓動一個線程是一個相當昂貴的操作。你肯定需要一個品牌新的線程,而不是使用線程池線程?考慮使用ThreadPool.QueueUserWorkItem或(最好是,如果您使用.NET 4)TaskFactory.StartNew

+1

這就是:-)我不知道當沒有更多的語句要執行時線程會終止。所以這是我需要的確切答案。非常感謝!!! – Brett

41

它真的必須是一個線程,或者它可以是一個任務嗎?

如果是這樣,最簡單的方法是:

Task.Factory.StartNew(() => SecondFoo()) 
+0

或只是'Task.Run' – Omu

1

除非你有需要非線程池中的線程特殊的情況下,只使用一個線程池線程這樣的:

Action secondFooAsync = new Action(SecondFoo); 

secondFooAsync.BeginInvoke(new AsyncCallback(result => 
     { 
     (result.AsyncState as Action).EndInvoke(result); 

     }), secondFooAsync); 

被稱爲EndInvoke的Gaurantees負責爲您進行清理。

+0

我已經使用beginInvoke在一個新線程中運行一個長處理報告。以下是關於BeginInvoke的MSDN文章:http://msdn.microsoft.com/en-us/library/2e08f6yc%28v=vs.71%29.aspx – William

+3

調用'ThreadPool.QueueUserWorkItem'更容易... –

-2

據我所知你需要的意思終止爲Thread.Abort()對不對?在這種情況下,您可以退出Foo()。或者您可以使用Process來捕捉線程。

Thread myThread = new Thread(DoWork); 

myThread.Abort(); 

myThread.Start(); 

過程例如:

using System; 
using System.Diagnostics; 
using System.ComponentModel; 
using System.Threading; 
using Microsoft.VisualBasic; 

class PrintProcessClass 
{ 

    private Process myProcess = new Process(); 
    private int elapsedTime; 
    private bool eventHandled; 

    // Print a file with any known extension. 
    public void PrintDoc(string fileName) 
    { 

     elapsedTime = 0; 
     eventHandled = false; 

     try 
     { 
      // Start a process to print a file and raise an event when done. 
      myProcess.StartInfo.FileName = fileName; 
      myProcess.StartInfo.Verb = "Print"; 
      myProcess.StartInfo.CreateNoWindow = true; 
      myProcess.EnableRaisingEvents = true; 
      myProcess.Exited += new EventHandler(myProcess_Exited); 
      myProcess.Start(); 

     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("An error occurred trying to print \"{0}\":" + "\n" + ex.Message, fileName); 
      return; 
     } 

     // Wait for Exited event, but not more than 30 seconds. 
     const int SLEEP_AMOUNT = 100; 
     while (!eventHandled) 
     { 
      elapsedTime += SLEEP_AMOUNT; 
      if (elapsedTime > 30000) 
      { 
       break; 
      } 
      Thread.Sleep(SLEEP_AMOUNT); 
     } 
    } 

    // Handle Exited event and display process information. 
    private void myProcess_Exited(object sender, System.EventArgs e) 
    { 

     eventHandled = true; 
     Console.WriteLine("Exit time: {0}\r\n" + 
      "Exit code: {1}\r\nElapsed time: {2}", myProcess.ExitTime, myProcess.ExitCode, elapsedTime); 
    } 

    public static void Main(string[] args) 
    { 

     // Verify that an argument has been entered. 
     if (args.Length <= 0) 
     { 
      Console.WriteLine("Enter a file name."); 
      return; 
     } 

     // Create the process and print the document. 
     PrintProcessClass myPrintProcess = new PrintProcessClass(); 
     myPrintProcess.PrintDoc(args[0]); 
    } 
} 
4

.NET中的線程由線程池管理,這樣你可以啓動它,忘掉它!考慮這個代碼。

new Thread(new ThreadStart(SecondFoo)).Start();