[英]Return values from two long running methods, using threads
I have a thread that connects to two network resources. 我有一个连接到两个网络资源的线程。 Each time I attempt a connection, it can take 10 seconds for a reply. 每次尝试建立连接时,回复可能需要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
}
Total time is twenty seconds, but I'd really like it to take only ten seconds -- launching threads each time I call GetResource, receiving a reply and then joining each thread to return control. 总时间为20秒,但是我真的希望它仅花费10秒-每次我调用GetResource时启动线程,接收答复,然后加入每个线程以返回控制权。
What's the best way to do this? 最好的方法是什么? Launch two threads that each return a value? 启动两个各自返回值的线程? Anonymous methods that take references to local variables? 引用局部变量的匿名方法? My head is spinning. 我的头在旋转。 Code is appreciated. 代码受到赞赏。
How about 怎么样
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
Short and sweet. 简短而甜美。
The easiest way that occurs to me to do so is to parallelize one of the calls on a worker thread while having the main thread perform the second initialization and wait. 对我而言,最简单的方法是并行化工作线程上的调用之一,同时让主线程执行第二次初始化并等待。 The following snipet should help to illustrate: 以下摘录应有助于说明:
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
For a more detailed discussion of thread synchronization techniques, you may wish to visit the MSDN article on the topic: http://msdn.microsoft.com/en-us/library/ms173179.aspx
有关线程同步技术的详细讨论,您可能希望访问有关该主题的MSDN文章: http://msdn.microsoft.com/en-us/library/ms173179.aspx
: http://msdn.microsoft.com/en-us/library/ms173179.aspx
These are always fun questions to ponder, and of course there's multiple ways to solve it. 这些总是值得思考的有趣问题,当然,有多种解决方法。
One approach that's worked well for me is to provide a callback method that each thread uses to pass back results and status. 对我而言,一种行之有效的方法是提供一种回调方法,每个线程都使用该方法来传回结果和状态。 In the following example, I use a List to keep track of running threads and put the results in a Dictionary. 在下面的示例中,我使用List来跟踪正在运行的线程,并将结果放入Dictionary中。
using System; 使用系统; using System.Collections.Generic; 使用System.Collections.Generic; using System.Linq; 使用System.Linq; using System.Text; 使用System.Text; using System.Threading; 使用System.Threading; using System.Timers; 使用System.Timers;
namespace ConsoleApplication1 { class Program { static Dictionary threadResults = new Dictionary(); 命名空间ConsoleApplication1 {类Program {静态Dictionary threadResults = new Dictionary(); static int threadMax = 2; 静态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);
}
}
} }
Try this on MSDN: "Asynchronous programming using delegates." 在MSDN上尝试以下操作:“使用委托进行异步编程”。
http://msdn.microsoft.com/en-us/library/22t547yb.aspx http://msdn.microsoft.com/en-us/library/22t547yb.aspx
-Oisin -Oisin
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.