1

I am trying to do a long process with multi threads. How can I get resutn value from threads? If I can get return values, I will update database according to the return value.

here is my code that calls the threads...

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();
}

here is the thread invoker.....

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

here is the real email sender

public int sendEmail(string to_,string subject_,string body_) {
    .......
    .......
    .......
    return 1;
}
Arif YILMAZ
  • 5,754
  • 26
  • 104
  • 189

3 Answers3

2

Instead of using thread you could using Task which offers many advantages over creating yourself the threads
Your code can be changed to something like this:

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

Update To get a behavior similar to BackgroundWorker you should synchronize your task with the current UI thread using the TaskScheduler.FromCurrentSynchronizationContext() so the code above can be written like this :

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

This article illustrate why you should use Task.Run over BackgroundWorker

Community
  • 1
  • 1
BRAHIM Kamel
  • 13,492
  • 1
  • 36
  • 47
1

In this situation you could just put your code at the end of sendEmail, or as part of the delegation to create the thread like:

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

Even better might be put an eventhandler into your code called something like "OnEmailSendComplete" and pass the return type into the handler.

That said, it's neater to use the new Async methods if the above is all your code is doing rather than writing your own thread handling.

Jim
  • 479
  • 2
  • 8
1

In .NET exists BackgroundWorker class which is the right way to handle time-consuming tasks in background. Try something like this:

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 --)
}

You need to create DoWork and RunWorkerCompleted handlers, but I'm sure you can find a lot of tutorials over the internet, for example:

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

Sending Arguments To Background Worker?

Community
  • 1
  • 1
Jan Kukacka
  • 1,196
  • 1
  • 14
  • 29
  • It is name of the function, that handles the DoWork event. For example: `private void bw_DoWork(object sender, DoWorkEventArgs e){ BackgroundWorker worker = sender as BackgroundWorker; ....}` – Jan Kukacka Nov 17 '14 at 12:46