user2659831
user2659831

Reputation: 25

Get variable from thread after method has finished executing

At the moment I have a class called Worker with a method DoWork which sends a string to a server and then the server returns a string.

class Worker
{

      public Worker(int id)
      {
           //Stuff
      }

      public string DoWork(string s)
      {
            //Manipulate s

            return s;
      }
}

Now what I'm trying to achieve is having multiple threaded Workers running the DoWork method and retrieving the value of the first method to return the s string, then closing all the threads.

This is what ive got so far:

class Program
{
        public string DoWork(string s);

        static void Main(string[] args)
        {
            string s = "String";
            Worker w1 = new Worker(1);
            Worker w2 = new Worker(2);
            Worker w3 = new Worker(3);

                Thread t1 = new Thread(() => w1.DoWork(s));
                Thread t2 = new Thread(() => w2.DoWork(s));
                Thread t3 = new Thread(() => w3.DoWork(s));
                t1.Start();
                t2.Start();
                t3.Start();
        }
}

Currently the program does not compile and I get the error:

DoWork(string) must declare a body because it is not marked abstract, extern or partial

I am also unsure as to how to retrieve the string (I only want the first returned value).

Is what I am trying to achieve possible?

Upvotes: 0

Views: 161

Answers (3)

Servy
Servy

Reputation: 203827

If you use the Task Parallel Library instead of raw tasks you can use Task.WaitAny to solve this problem very effectively.

string s = "String";

var tasks = Enumerable.Range(0, 3)
    .Select(i => Task.Run(()=> new Worker(i).DoWork(s)))
    .ToArray();

var finishedindex = Task.WaitAny(tasks);
Console.WriteLine(tasks[finishedindex].Result);

Upvotes: 0

Andrew
Andrew

Reputation: 3796

You can also use delegate for asynchronous calls:

public delegate string AsyncWorkCaller(string s);

and the code to execute it:

Worker w = new Worker(0);
AsyncWorkCaller caller = new AsyncWorkCaller(w.DoWork);

string s = "your string";
caller.BeginInvoke(s, WorkCallback, null);

and the callback method:

private void WorkCallback(IAsyncResult ar)
{
    AsyncResult result = (AsyncResult)ar;
    AsyncWorkCaller caller = (AsyncWorkCaller)result.AsyncDelegate;

    string returnValue = caller.EndInvoke(ar);

    //manipulate the new s value here
 }

http://msdn.microsoft.com/en-us/library/2e08f6yc%28v=vs.110%29.aspx

Upvotes: 0

dcastro
dcastro

Reputation: 68640

You should remove the DoWork declaration from Program to remove the compilation error.

Also, if you want your threads to return values to your main thread, and if you're using .NET 4/4.5, consider using Task<T>, instead of using threads directly. Tasks would serve you better.

Task<string> task1 = Task.Run(() => w1.DoWork(s));


//non-blocking
string result1 = await task1;

//or

//blocking call, "equivalent" of "thread.Join()"
string result1 = task1.Result;

Upvotes: 1

Related Questions