C#从线程中调用的函数返回值
我有一个计算线程函数,它使用Invoke从其他线程调用消息函数,我希望计算线程从该消息函数中获取值(valuetype,比如integer)。我该怎么做 问题是在调用(…)之后,我仍然会得到x变量的旧值,而我期望值为15C#从线程中调用的函数返回值,c#,multithreading,invoke,value-type,C#,Multithreading,Invoke,Value Type,我有一个计算线程函数,它使用Invoke从其他线程调用消息函数,我希望计算线程从该消息函数中获取值(valuetype,比如integer)。我该怎么做 问题是在调用(…)之后,我仍然会得到x变量的旧值,而我期望值为15 delegate void mes_del(object param); void MyThreadFunc() { ... int x = 5; object [] parms = new object []{x}; Invoke(new mes_del(MessageFu
delegate void mes_del(object param);
void MyThreadFunc()
{
...
int x = 5;
object [] parms = new object []{x};
Invoke(new mes_del(MessageFunc), (object)parms);
...
}
void MessageFunc(object result)
{
int res = 15;
(result as object[])[0] = res;
}
我尝试了一些方法,比如使用object[],object作为参数,但没有成功。我认为装箱/拆箱操作应该在这种情况下发生,但事实并非如此。
我应该像在.NET事件模式中那样使用辅助类型,而像在.NET事件模式中那样创建中介对象吗
阶级持有者
{
公共int x;
}
上面的代码所做的是声明一个局部变量,将其赋值为5,然后构造一个object[]
数组,其中包含一个作为该局部变量副本的元素
然后将此数组传递到Invoke
调用中
我想你会发现在调用Invoke
之后,parms[0]
是15。但这并不影响x
,任何方法都必须将其作为ref
参数传递,才能修改其局部值
我以前看到的是这样的:
class Box<T>
{
public T Value { get; set; }
}
类框
{
公共T值{get;set;}
}
然后你可以做:
void MyThreadFunc()
{
var x = new Box<int> { Value = 5 };
// By the way, there's really no reason to define your own
// mes_del delegate type.
Invoke(new Action<Box<int>>(MessageFunc), x);
}
void MessageFunc(Box<int> arg)
{
arg.Value = 15;
}
void MyThreadFunc()
{
var x=新框{Value=5};
//顺便说一下,真的没有理由定义你自己的
//mes_del委托类型。
调用(新操作(MessageFunc),x);
}
void MessageFunc(框参数)
{
参数值=15;
}
上面的代码所做的是声明一个局部变量,将其赋值为5,然后构造一个object[]
数组,其中包含一个作为该局部变量副本的元素
然后将此数组传递到Invoke
调用中
我想你会发现在调用Invoke
之后,parms[0]
是15。但这并不影响x
,任何方法都必须将其作为ref
参数传递,才能修改其局部值
我以前看到的是这样的:
class Box<T>
{
public T Value { get; set; }
}
类框
{
公共T值{get;set;}
}
然后你可以做:
void MyThreadFunc()
{
var x = new Box<int> { Value = 5 };
// By the way, there's really no reason to define your own
// mes_del delegate type.
Invoke(new Action<Box<int>>(MessageFunc), x);
}
void MessageFunc(Box<int> arg)
{
arg.Value = 15;
}
void MyThreadFunc()
{
var x=新框{Value=5};
//顺便说一下,真的没有理由定义你自己的
//mes_del委托类型。
调用(新操作(MessageFunc),x);
}
void MessageFunc(框参数)
{
参数值=15;
}
您是说从Windows窗体调用控件吗?如果是,该方法还可以返回结果,因此您可以编写:
delegate int mes_del(int param);
void MyThreadFunc() {
int x = 5;
object [] parms = new object []{x};
x = (int)Invoke(new mes_del(MessageFunc), x);
// you'll get a new value of 'x' here (incremented by 10)
}
int MessageFunc(int result) {
return result + 10;
}
您的代码可能不起作用,因为您正在访问x
,而不是从数组中选择一个新值(应该修改)。但是,使用返回新值的重载应该是更清晰的解决方案 您是说从Windows窗体调用控件吗?如果是,该方法还可以返回结果,因此您可以编写:
delegate int mes_del(int param);
void MyThreadFunc() {
int x = 5;
object [] parms = new object []{x};
x = (int)Invoke(new mes_del(MessageFunc), x);
// you'll get a new value of 'x' here (incremented by 10)
}
int MessageFunc(int result) {
return result + 10;
}
您的代码可能不起作用,因为您正在访问x
,而不是从数组中选择一个新值(应该修改)。但是,使用返回新值的重载应该是更清晰的解决方案 仅从方法返回值
void MyThreadFunc()
{
...
int x = 5;
object [] parms = new object []{x};
var callResult = (int)Invoke((Func<object,int>)MessageFunc, (object)parms);
...
}
int MessageFunc(object result)
{
int res = 15;
return res;
}
void MyThreadFunc()
{
...
int x=5;
object[]parms=新对象[]{x};
var callResult=(int)Invoke((Func)MessageFunc,(object)parms);
...
}
int MessageFunc(对象结果)
{
int res=15;
返回res;
}
只需从方法返回值
void MyThreadFunc()
{
...
int x = 5;
object [] parms = new object []{x};
var callResult = (int)Invoke((Func<object,int>)MessageFunc, (object)parms);
...
}
int MessageFunc(object result)
{
int res = 15;
return res;
}
void MyThreadFunc()
{
...
int x=5;
object[]parms=新对象[]{x};
var callResult=(int)Invoke((Func)MessageFunc,(object)parms);
...
}
int MessageFunc(对象结果)
{
int res=15;
返回res;
}
对于您的问题,最好的答案可能是在.NET 4.0中
在这里,主线程被阻塞,直到另一个线程上调用的方法返回结果。如果主线程已经返回结果并到达WriteLine,则没有阻塞
Task task = Task.Factory.StartNew(SomeMethod);
Console.WriteLine(task.Result);
public static string SomeMethod()
{
return "Hello World";
}
或
也许对你的问题最好的答案是在.NET 4.0中
在这里,主线程被阻塞,直到另一个线程上调用的方法返回结果。如果主线程已经返回结果并到达WriteLine,则没有阻塞
Task task = Task.Factory.StartNew(SomeMethod);
Console.WriteLine(task.Result);
public static string SomeMethod()
{
return "Hello World";
}
或
给我们多一点代码。在代码中调用Invoke
之后会发生什么?MessageFunc
正在正确地更改值,因此您没有等待异步任务完成,或者您获取修改值的代码不正确。@Jim:它没有更改x
的值@丹涛:当然它不会改变x
的值@吉姆:OP说,“问题是我在调用(…)之后仍然得到x变量的旧值”;您的评论听起来像是在暗示问题与等待异步调用有关,而实际上OP的当前代码永远不会更改x
的值。另外,假设OP使用的是Windows窗体,Control.Invoke
会自动等待UI执行代码(而不是Control.BeginInvoke
,后者不会执行)。@Dan Tao:我想我给了比预期更多的信任。我没有想到OP期望自动地改变代码> x>代码>。我想他知道他必须从数组中获取新值x
。是的,我把Invoke
理解为BeginInvoke
。给我们多一点代码。在代码中调用Invoke
之后会发生什么?MessageFunc
正在正确地更改值,因此您没有等待异步任务完成,或者您获取修改值的代码不正确。@Jim:它没有更改x
的值@丹涛:当然它不会改变x
的值@吉姆:OP说,“问题是我