C# 在方法完成执行后从线程获取变量

C# 在方法完成执行后从线程获取变量,c#,multithreading,C#,Multithreading,目前,我有一个名为Worker的类,它有一个方法DoWork,它向服务器发送一个字符串,然后服务器返回一个字符串 class Worker { public Worker(int id) { //Stuff } public string DoWork(string s) { //Manipulate s return s; } } 现在我试图实现

目前,我有一个名为Worker的类,它有一个方法
DoWork
,它向服务器发送一个字符串,然后服务器返回一个字符串

class Worker
{

      public Worker(int id)
      {
           //Stuff
      }

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

            return s;
      }
}
现在我试图实现的是让多个线程工作者运行
DoWork
方法,检索第一个方法的值以返回
s
字符串,然后关闭所有线程

这就是我目前所得到的:

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();
        }
}
目前程序未编译,我得到错误:

DoWork(string)必须声明一个主体,因为它没有标记为抽象、外部或部分

我也不确定如何检索字符串(我只想要第一个返回值)


我试图实现的是可能的吗?

您应该从
程序中删除
DoWork
声明以删除编译错误

此外,如果您希望线程返回值到主线程,并且如果使用.NET 4/4.5,请考虑使用<代码>任务<代码>,而不是直接使用线程。任务会更好地为你服务

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;
Task task1=Task.Run(()=>w1.DoWork);
//非阻塞
字符串result1=等待任务1;
//或
//阻塞调用,相当于“thread.Join()”
字符串result1=task1.Result;

您还可以将委托用于异步调用:

public delegate string AsyncWorkCaller(string s);
以及执行它的代码:

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

string s = "your string";
caller.BeginInvoke(s, WorkCallback, null);
以及回调方法:

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
 }

如果使用任务并行库而不是原始任务,则可以使用
Task.WaitAny
非常有效地解决此问题

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

也许你应该使用为这个用例设计的BackgroundWorker类:我选择这个作为我的答案,因为其他两个都使用.NET 4.0中的东西(我的坏习惯是不说我使用的是哪个.NET版本,对不起)