C# C Func委托引发线程异常
所以,也许我误解了Func的用法,但是C# C Func委托引发线程异常,c#,C#,所以,也许我误解了Func的用法,但是 Func<ComboBox, string> getCurrentValue = s => s.SelectedValue.ToString(); 从我的Workerthread调用getCurrentValuecb_消息_类型时创建线程错误。 获得组合框选定值的最佳解决方案是什么 非常感谢,, 雷特 编辑 MSDN lambda表达式的基础类型是泛型Func委托之一。这使得可以将lambda表达式作为参数传递,而无需将其显式分配给委托
Func<ComboBox, string> getCurrentValue = s => s.SelectedValue.ToString();
从我的Workerthread调用getCurrentValuecb_消息_类型时创建线程错误。
获得组合框选定值的最佳解决方案是什么
非常感谢,,
雷特
编辑
MSDN
lambda表达式的基础类型是泛型Func委托之一。这使得可以将lambda表达式作为参数传递,而无需将其显式分配给委托。由于windows控件具有线程关联性,因此有两个选项: 在执行线程代码之前查询此数据,例如,将其作为状态传递给工作程序 通过Control.Invoke在worker中查询它 由于第一个变量很小,我将给出第二个使用捕获变量的示例:
object value = null;
yourCombo.Invoke((MethodInvoker) delegate {value=yourCombo.SelectedValue;});
string s = value.ToString();
这里,委托{…}内的位发生在UI线程上,即使它周围的代码在工作线程上。您可以在func内部混合上述内容,也可以在切换线程后调用整个func。您需要调用Control.Invoke(使用该委托调用),或者让委托本身调用它。
使用lambda表达式不会改变Windows窗体的线程要求-它只是使创建委托更容易
您可能希望使用一种方便的方法来执行此操作:
// (Untested)
public static Func<TControl, TResult> WrapInvocation(Func<TControl,TResult> func)
where TControl : Control
{
return control => {
return (TResult) control.Invoke(func);
};
}
用作:
Func<ComboBox, string> getCurrentValue = s => s.SelectedValue.ToString();
getCurrentValue = WrapInvocation(getCurrentValue);
然后可以从任何线程调用getCurrentValuecomboBox。问题是UI控件只能在UI线程上使用 您需要在另一个线程中调用Invoke方法,如下所示:
Func<ComboBox, string> getCurrentValue =
s => s.Invoke(new Func<object>(() => s.SelectedValue)).ToString();
Invoke方法接受委托并在UI线程上执行它。一般来说,您不能从创建UI控件的线程以外的线程访问UI控件。要克服这一问题,您必须检查相关控件和分支上的ISynchronizeInvoke.InvokeRequired、调用委托等,或者使用SynchronizationContext。第一个选项非常麻烦,而第二个选项非常优雅:
var synchronizationContext = WindowsFormsSynchronizationContext.Current;
string currentValue = "";
synchronizationContext.Send(
() => currentValue = getCurrentValue(comboBox),
null);
如果线程只是在读取ComboBox,那么如果可行的话,最好的选择可能是在线程上有一个事件处理程序,它可以在ComboBox值发生任何更改时获取该值,然后通过可以从任何线程读取的属性公开该值