使用线程从两个长时间运行的方法返回值

时间:2009-08-26 17:03:30

标签: c# .net multithreading

我有一个连接到两个网络资源的线程。每次尝试连接时,都可能需要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
} 

总时间是20秒,但我真的希望它只用十秒钟 - 每次调用GetResource时启动线程,接收回复然后加入每个线程以返回控制。

最好的方法是什么?启动两个线程,每个线程返回一个值?引用局部变量的匿名方法?我的头在旋转。代码表示赞赏。

4 个答案:

答案 0 :(得分: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

简短又甜蜜。

答案 1 :(得分: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

答案 2 :(得分:1)

这些总是很有趣的问题需要思考,当然有多种方法可以解决它。

对我来说效果很好的一种方法是提供每个线程用来传回结果和状态的回调方法。在下面的示例中,我使用List来跟踪正在运行的线程并将结果放在Dictionary中。

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

命名空间ConsoleApplication1 {     课程     {         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);
    }
}

}

答案 3 :(得分:0)

在MSDN上试试:“使用代理进行异步编程。”

http://msdn.microsoft.com/en-us/library/22t547yb.aspx

-Oisin