2011-06-07 119 views
3

我有两个线程的应用程序。其中一个(T1)是主要的GUI形式,另一个(T2)是循环中的函数。当T2获取一些信息时必须用GUI的形式调用函数。 我不确定我是否做得对。beginInvoke,GUI和线程

T2调用函数FUNCTION,它以GUI的形式更新某些东西。

public void f() { 
     // controler.doSomething(); 
    } 


public void FUNCTION() { 

    MethodInvoker method = delegate { 
      f(); 
    }; 

    if (InvokeRequired) { 
     BeginInvoke(method); 
    } else { 
      f(); 
    } 
} 

但是现在我必须声明两个函数。它如何只使用一个功能?或者它是如何正确的。

回答

14

你可以通过调用调用自己在一个单独的方法做到这一点:

public void Function() 
{ 
    if (this.InvokeRequired) 
    { 
     this.BeginInvoke(new Action(this.Function)); 
     return; 
    } 

    // controller.DoSomething();   
} 

编辑回应评论:

如果你需要传递额外的参数,你可以做到这一点使用lambda表达式如下:

public void Function2(int someValue) 
{ 
    if (this.InvokeRequired) 
    { 
     this.BeginInvoke(new Action(() => this.Function2(someValue))); 
     return; 
    } 

    // controller.DoSomething(someValue);   
} 
+1

尼斯模式。如果您是从第二个线程调用的,则可以使用一个递归调用来调用自己。我认为调用应该是同步完成的,所以来自第二个线程的调用(看起来是同步的;只是一个普通的方法调用)将以与从GUI线程调用相同的方式工作,在返回之前执行适当的任务。 – KeithS 2011-06-07 16:14:58

+0

有趣:我没有看到它这样做......它不会导致无限循环? – IAbstract 2011-06-07 16:15:26

+0

@nirmus:在大括号之后 - 我认为目标是删除第二个函数[“f()”] - 在这里,它被放置在大括号后的主函数中。基本上,如果你需要调用,你自己调用,如果没有,你可以做任何你想做的事情...... – 2011-06-07 16:16:13

3

看起来不错。您可以将匿名代理更改为一个更清洁的lambda。为了摆脱F()方法声明中,你可以内联的代码放到委托,那么要么调用委托作为MethodInvoker或简单地调用它,就象任何其它方法:

public void FUNCTION() { 

    MethodInvoker method =()=> controller.doSomething(); 

    if (InvokeRequired) { 
     BeginInvoke(method); 
    } else { 
      method(); 
    } 
} 
+0

这是很好的解决方案。我必须学习一些关于lambda函数的内容,因为我看到它有一个有趣的可能性。感谢帮助。 – nirmus 2011-06-07 16:23:21