如何在线程完成时获取返回值

时间:2014-11-17 12:11:40

标签: c# wpf multithreading return

我正在尝试使用多线程进行漫长的过程。如何从线程获得resutn值?如果我可以获得返回值,我将根据返回值更新数据库。

这是我调用线程的代码......

foreach (var obj in elements) {
         string body_ = @"<html><head></head><body><a href='http://localhost:5111/Default.aspx?id=" + obj.ID + @"&answer=yes'>Evet</a> - <a href='http://localhost:5111/Default.aspx?id=" + obj.ID + @"&answer=no'>Hayır</a></body></html>";
         Thread thread = new Thread(() => sendEmailThread(obj.ALICI, obj.KONU, body_));
         thread.Start();
}

这是线程调用者.....

private void sendEmailThread(string ALICI, string KONU, string body_)
{
     this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate() { sendEmail(ALICI, KONU, body_); } );
}

这是真正的电子邮件发件人

public int sendEmail(string to_,string subject_,string body_) {
    .......
    .......
    .......
    return 1;
}

3 个答案:

答案 0 :(得分:2)

您可以使用Task代替使用线程,而不是创建自己的线程 您的代码可以更改为:

var task = Task<int>.Factory.StartNew(
     () => sendEmailThread(obj.ALICI, obj.KONU, body_));
task.ContinueWith(() => {var result = task.Result;}); 

<强>更新 要获得类似于BackgroundWorker的行为,您应该使用TaskScheduler.FromCurrentSynchronizationContext()将任务与当前UI线程同步 所以上面的代码可以这样写:

var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();
task.ContinueWith(() => { var result = task.Result; }, UISyncContext); 

这个article说明了为什么要在BackgroundWorker上使用Task.Run

答案 1 :(得分:1)

在这种情况下,您可以将代码放在sendEmail的末尾,或者作为委派的一部分来创建如下的线程:

private void sendEmailThread(string ALICI, string KONU, string body_)
{
    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate() { 
                     var result = sendEmail(ALICI, KONU, body_); 
                     SomeDBUpdate(result);
                     } );
}

甚至可以更好地将一个事件处理程序放入你的代码中,例如&#34; OnEmailSendComplete&#34;并将返回类型传递给处理程序。

也就是说,如果以上所有代码都是在做,而不是编写自己的线程处理,那么使用新的Async方法更为全面。

答案 2 :(得分:1)

在.NET中存在BackgroundWorker类,这是在后台处理耗时任务的正确方法。尝试这样的事情:

foreach (var obj in elements) {
    BackgroundWorker bw = new BackgroundWorker();
    string body_ = @"<html><head></head><body><a href='http://localhost:5111/Default.aspx?id=" + obj.ID + @"&answer=yes'>Evet</a> - <a href='http://localhost:5111/Default.aspx?id=" + obj.ID + @"&answer=no'>Hayır</a></body></html>";

    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

    bw.RunWorkerAsync(-- your params here --)
}

您需要创建DoWork和RunWorkerCompleted处理程序,但我确信您可以通过Internet找到大量教程,例如:

http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

Sending Arguments To Background Worker?