2009-08-26 52 views
2

我有一個線程連接到兩個網絡資源。每次嘗試連接時,回覆可能需要10秒。返回兩個長時間運行的方法的值,使用線程

void MyThread() 
{ 
    //this takes ten seconds 
    Resource r1 = MySystem.GetResource(ipAddress1); 

    //this takes ten seconds 
    Resource r2 = MySystem.GetResource(ipAddress2); 

    //do stuff with ep1 and ep2 
} 

總時間二十歲秒,但我真的很喜歡它只拿10秒 - 啓動線程每個我叫佔用資源的時間,收到答覆,然後加入每個線程返回控制。

這樣做的最好方法是什麼?啓動兩個線程,每個線程都返回一個值?引用局部變量的匿名方法?我的頭在旋轉。代碼表示讚賞。

回答

4

如何

Resource r1 = null; // need to initialize, else compiler complains 
Resource r2 = null; 

ThreadStart ts1 = delegate { 
    r1 = MySystem.GetResource(ipAddress1); 
}; 
ThreadStart ts2 = delegate { 
    r2 = MySystem.GetResource(ipAddress2); 
}; 
Thread t1 = new Thread(ts1); 
Thread t2 = new Thread(ts2); 
t1.Start(); 
t2.Start(); 
// do some useful work here, while the threads do their thing... 
t1.Join(); 
t2.Join(); 
// r1, r2 now setup 

簡短而甜美。

+0

我也喜歡這個。我希望社區能幫助我找出最好的方法 – MedicineMan 2009-08-26 17:27:53

+0

出於好奇,是否有一個原因爲什麼你選擇背景初始化?從我所看到的情況來看,現在您將擁有兩個後臺線程的開銷,而主線程處於空閒狀態並等待它們完成。 – 2009-08-26 17:30:32

+0

@Jesse Squire:這只是一個例子。據我所知,真正的應用程序可能有N個資源,其中N> 2。主線程在執行'Join'之前可能有其他想做的事情。 – 2009-08-26 17:54:19

1

是發生在我這樣做最簡單的方法是同時具有主線程中執行第二初始化並等待並行調用的一個上一個工作線程。下面snipet應有助於說明:

ManualResetEvent r1Handle = new ManualResetEvent(false); 
Resource   r1  = null; 
Resource   r2  = null; 

// Make the threadpool responsible for populating the 
// first resource. 

ThreadPool.QueueUserWorkItem((state) => 
{ 
    r1 = MySystem.GetResource(ipAddress1); 

    // Set the wait handle to signal the main thread that 
    // the work is complete. 

    r1Handle.Set(); 
}); 

// Populate the second resource. 

r2 = MySystem.GetResource(ipAddress2); 

// Wait for the threadpool worker to finish. 

r1Handle.WaitOne(); 

// ... Do more stuff 

對於線程同步技術的更詳細的討論,你不妨請訪問MSDN文章的題目是http://msdn.microsoft.com/en-us/library/ms173179.aspx

1

這些總是有趣的問題來思考,當然有多種方法來解決它。

對我來說很好的一種方法是提供一個回調方法,每個線程都使用回調方法來返回結果和狀態。在下面的示例中,我使用List來跟蹤正在運行的線程並將結果放入Dictionary中。

using System; using System.Collections.Generic; 使用System.Linq的; 使用System.Text;使用System.Threading的 ;使用System.Timers的 ;

命名空間ConsoleApplication1 { 類節目 { 靜態字典threadResults =新詞典(); static int threadMax = 2;

static void Main(string[] args) 
    { 
     List<Thread> runningThreads = new List<Thread>(); 
     for (int i = 0; i < threadMax; i++) 
     { 
      Worker worker = new Worker(); 
      worker.Callback = new Worker.CallbackDelegate(ThreadDone); 
      Thread workerThread = new Thread(worker.DoSomething); 
      workerThread.IsBackground = true; 
      runningThreads.Add(workerThread); 
      workerThread.Start(); 
     } 

     foreach (Thread thread in runningThreads) thread.Join(); 
    } 

    public static void ThreadDone(int threadIdArg, object resultsArg) 
    { 
     threadResults[threadIdArg] = resultsArg; 
    } 
} 


class Worker 
{ 
    public delegate void CallbackDelegate(int threadIdArg, object resultArg); 
    public CallbackDelegate Callback { get; set; } 
    public void DoSomething() 
    { 
     // do your thing and put it into results 
     object results = new object(); 
     int myThreadId = Thread.CurrentThread.ManagedThreadId; 
     Callback(myThreadId, results); 
    } 
} 

}

+0

似乎有點複雜。如果其他一些方法不能解決問題,可能會是一個有趣的選擇 – MedicineMan 2009-08-27 17:35:12

相關問題