0

So i have been multithreading lately,and since im new to this im probably doing something basic wrong..

Thread mainthread = new Thread(() => threadmain("string", "string", "string"));
mainthread.Start();

the above code works flawlessly but now i want to get a value back from my thread. to do that i searched on SO and found this code:

  object value = null; 
  var thread = new Thread(
    () =>
    {
      value = "Hello World"; 
    });
  thread.Start();
  thread.Join();
MessageBox.Show(value);
}

and i dont know how to combine the two.

the return value will be a string.

thank you for helping a newbie,i tried combining them but got errors due to my lack of experience

edit:

my thread:

public void threadmain(string url,string search, string regexstring) {

    using (WebClient client = new WebClient()) // WebClient class inherits IDisposable
    {
        string allthreadusernames = "";
        string htmlCode = client.DownloadString(url);

        string[] htmlarray = htmlCode.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string line in htmlarray)
        {
            if (line.Contains(search))
            {

                var regex = new Regex(regexstring);
                var matches = regex.Matches(line);
                foreach (var singleuser in matches.Cast<Match>().ToList())
                {
                    allthreadusernames = allthreadusernames + "\n" + singleuser.Groups[1].Value;


                }
            }
        }

        MessageBox.Show(allthreadusernames);

    }

}
tim_po
  • 105
  • 10
  • check out async/await – Sam Axe Mar 05 '15 at 13:34
  • you don't want to get a value from a thread you want to retrieve a value from a function. Threads don't have values themselfs. They can be used to process work. The result from that work you want to return. – Blaatz0r Mar 05 '15 at 13:34

2 Answers2

2

An easy solution would be to use another level of abstraction for asynchronous operations: Tasks.

Example:

public static int Calculate()
{
  // Simulate some work

  int sum = 0;
  for (int i = 0; i < 10000; i++)
  {
    sum += i;
  }
  return sum;
}

// ...

var task = System.Threading.Tasks.Task.Run(() => Calculate());
int result = task.Result; // waits/blocks until the task is finished

In addition to task.Result, you can also wait for the task with await task (async/await pattern) or task.Wait (+ timeout and/or cancellation token).

Sebastian Negraszus
  • 11,915
  • 7
  • 43
  • 70
  • is it as efficient? if so what is the difference? – tim_po Mar 05 '15 at 13:44
  • @tim_po way more efficient. spinning up threads is simply *the wrong* way (not always though). therefore tasks where created, to give a certain abstraction of threads (tasks do not need to be executed on different threads, rather the scheduler decides this ...). see eg http://blog.slaks.net/2013-10-11/threads-vs-tasks/, http://stackoverflow.com/a/13429164/57508 –  Mar 05 '15 at 13:47
  • The difference is basically that with tasks abstract away the responsibility of creating thread from you the operation system and let you concentrate on providing it the work you want it to do, which is more efficient API wise and performance wise as well( Generic that was introduced, new thread pool implementation ...ect) – Roman Ambinder Mar 05 '15 at 13:53
  • 5
    I feel like this answer could benefit from being related back to how the asker might accomplish something like this using tasks. You and I know it would be pretty straight-forward, but not everyone will. As it stands, this is something of a link-only answer. – Matthew Haugen Mar 06 '15 at 00:04
  • @MatthewHaugen Added an example – Sebastian Negraszus Mar 09 '15 at 11:19
  • @LegoStormtroopr Added an example – Sebastian Negraszus Mar 09 '15 at 11:19
1

Threads aren't really supposed to behave like functions. The code you found still lacks synchronization/thread-safety of reading/writing the output variable.

Task Parallel Library provides a better abstraction, Tasks.

Your problem can then be solved by code similar to this:

var result = await Task.Run(() => MethodReturningAValue());

Running tasks like this is actually more lightweight, as it only borrows an existing thread from either the SynchronizationContext or the .NET thread pool, with low overhead.

I highly recommend Stephen Cleary's blog series about using tasks for parallelism and asynchronicity. It should answer all your further questions.

Honza Brestan
  • 10,637
  • 2
  • 32
  • 43
  • i tried using threads and its VERY slow,with threads i was able to do many operations at the same time but the task seems to wait.. – tim_po Mar 05 '15 at 14:06
  • In my example the created task is being awaited. If you omit the `await` keyword (or [`Wait`](https://msdn.microsoft.com/en-us/library/dd235635(v=vs.110).aspx) method/[`Result`](https://msdn.microsoft.com/en-us/library/dd321468(v=vs.110).aspx) property), you may start multiple Tasks simultaneously and then use for example `await `[`Task.WhenAll`](https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.whenall%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396) to synchronize. – Honza Brestan Mar 05 '15 at 14:10
  • var taskresult = Task.Run(() => threadmain("string", "string", "string")); MessageBox.Show(taskresult); //doesnt work,tells me i cant turn into string? – tim_po Mar 05 '15 at 14:20