2009-08-26 38 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

相关问题