2011-03-03 79 views
0

我有一个计算线程函数,它使用Invoke从其他线程调用消息函数,我希望计算线程从该消息函数中获取value(value的类型,如整数)。我怎样才能做到这一点?C#线程中调用函数的返回值

的问题是,我的invoke(...)后,仍然得到变量x的原值和我预计的15

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

值我试着像使用对象[],对象与参数的一些方法没有成功。我虽然拳击/拆箱操作应该发生在这种情况下,但他们没有。 我应该像使用.NET事件模式一样使用辅助类型并创建中介对象,如 类持有者 public int x; }

+0

给我们多一点的代码。在你的代码中调用'Invoke'之后会发生什么? 'MessageFunc'正确地更改了值,所以要么不等待异步任务完成,要么代码获取修改后的值不正确。 – 2011-03-03 15:43:49

+0

@Jim:它不会改变'x'的值! – 2011-03-03 16:09:16

+0

@丹涛:当然不会改变'x'的价值! – 2011-03-03 19:35:20

回答

4
int x = 5; 
object [] parms = new object []{x}; 

什么上面的代码的作用是声明一个局部变量,分配给它的值5,然后构造一个object[]数组包含一个元素它是局部变量的副本

然后您将此数组传递给您的Invoke调用。

我想你会发现,Invoke被调用后,parms[0]是15但这并不影响x,这实际上将要传递的ref参数任何方法能够修改其当地价值。


我所看到之前完成是这样的:

class Box<T> 
{ 
    public T Value { 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; 
} 
+0

Just Fyi:['StrongBox '](http://msdn.microsoft.com/en-us/library/bb549038.aspx)class – Ani 2011-03-03 15:52:05

+0

@Ani:是的,我真的注意到了。但是这让我感到紧张:“这个API支持.NET Framework基础结构,并不打算直接从你的代码中使用。”几乎听起来像他们保留刚刚摆脱那个班的权利。 (另外,它在一个相当晦涩的命名空间中。) – 2011-03-03 15:56:40

1

你是从Windows窗体谈论Control.Invoke?如果是,该方法还可以返回结果,所以你可以写:

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而不是从阵列选择一个新的值(即应修改)。但是,使用返回新值的重载应该是更清晰的解决方案。

0

刚刚从方法的返回值

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; 
} 
+0

你的例子不会编译。 'mes_del'委托类型返回'void',所以'new mes_del(MessageFunc)'会给出一个错误,即MessageFunc具有错误的返回类型。 – 2011-03-04 14:36:44

0

也许最好的回答你的问题是在.NET 4.0中System.Threading.Tasks

这里主要线程被阻塞,直到结果是通过呼吁该方法返回其他线程。如果主线程已经返回结果到达WriteLine,则不会阻塞。

Task task = Task.Factory.StartNew(SomeMethod); 
Console.WriteLine(task.Result); 

public static string SomeMethod() 
{ 
    return "Hello World"; 
} 

OR

Task task = Task.Factory.StartNew(() => { return "Hello World"; }); 
Console.WriteLine(task.Result); 

Check this blog for more interesting samples.