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