MethodInvoker + lambda +参数+交叉线程操作
本文关键字:线程 操作 参数 lambda MethodInvoker | 更新日期: 2023-09-27 17:53:11
我用这个来改变其他线程的一些东西:
MethodInvoker m = () => { login_submit.Text = "Login"; };
if (InvokeRequired)
{
BeginInvoke(m);
}
else
{
Invoke(m);
}
运行正常
如何将参数传递给lambda表达式?
我想做这样的事情:
MethodInvoker m = (string txt) => { login_submit.Text = txt; };
if (InvokeRequired)
{
BeginInvoke(m); // I need to pass txt string in some way here.
}
else
{
Invoke(m); // I need to pass txt string in some way here.
}
如果这是您的常见场景,我建议编写一个扩展方法:
public static class ControlExtensions
{
public static void EnsureInvokeAsync(this Control control, Action action)
{
if (control.InvokeRequired) control.BeginInvoke(action);
else action();
}
}
class MyControl : UserControl
{
void M(string s)
{
// the lambda will capture the string in a closure
// the compiler does all the hard work for you
this.EnsureInvokeAsync(() => _button.Text = s);
}
}
此外,您应该考虑使用BackgroundWorker
或任务进行异步操作。
如果invokerequirequired为false,那么您根本不需要担心调用任何东西-您已经在正确的线程上了。
一个更好的解决方案可能是这样的:
public delegate void InvokerDelegate(string data);
public void DoStuff(string data){
login_submit.Text = data;
}
,然后调用时do:
if (InvokeRequired){
Invoke(InvokerDelegate(DoStuff), "something");
}
else{
DoStuff("Something");
}
您将看到的一个相当常见的模式是对在多线程环境中操作GUI的函数做这样的操作
public delegate void InvokerDelegate();
public void DoGuiStuff(){
if (login_submit.InvokeRequired){
login_submit.Invoke(InvokerDelegate(DoGuiStuff));
return;
}
login_submit.Text = "Some value";
}
如果使用上面的模式,函数检查是否需要调用,如果需要,则在正确的线程上调用自己。然后返回。当它调用自己时,检查是否需要调用返回false,因此它不需要再次调用自己-它只是运行代码。
编辑:我只是回到winforms,并试图使用这种模式,只是花了几个令人沮丧的分钟试图找出为什么我不能调用lambda。我想我最好回来更新这个答案,以添加所需的转换,以防其他人试图使用它。
MethodInvoker
是一个没有任何参数的委托类型。如果我理解正确的话,你可以这样做:
string txt = "some text";
MethodInvoker m = () => { login_submit.Text = txt; };
可以使用闭包将值传递到lambda的主体中。
string value = "Login";
MethodInvoker m = () => { login_submit.Text = value; };
if (InvokeRequired)
{
BeginInvoke(m); // I need to pass txt string in some way here.
}
else
{
Invoke(m); // I need to pass txt string in some way here.
}
或者可以使用类成员的数据