Returns values from two long methods using streams
I have a thread that connects to two network shares. Every time I try to connect, it may take 10 seconds to respond.
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
}
The total time is twenty seconds, but I would really like it to take only ten seconds - starting threads every time I call GetResource, I get a response, and then I attach to each thread to return control.
What's the best way to do this? Start two threads, each one returning a value? Anonymous methods that refer to local variables? My head is spinning. The code is being evaluated.
source to share
What 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.
source to share
The easiest way that comes up to me is to parallelize one of the calls to the worker thread, and the main thread does the second initialization and wait. The following snippet should help 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 in-depth discussion of thread synchronization technologies, you can visit the MSDN article on the topic: http://msdn.microsoft.com/en-us/library/ms173179.aspx
source to share
These are always fun questions to ponder, and of course there are several ways to solve it.
One approach that worked well for me is to provide a callback method that each thread uses to pass results and status. In the following example, I use a List to track the execution of threads and put the results into a dictionary.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Timers;
namespace ConsoleApplication1 {cool program {static dictionary threadResults = new dictionary (); 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);
}
}
}
source to share
Try this on MSDN: "Asynchronous Programming Using Delegates".
http://msdn.microsoft.com/en-us/library/22t547yb.aspx
-Oisin
source to share