【问题标题】:How to get GUI control's property value from another thread如何从另一个线程获取 GUI 控件的属性值
【发布时间】:2011-03-07 08:10:03
【问题描述】:

VS2005 / 框架 2.0 / VB.NET

我正在使用 BackgroundWorker 控件做一些长时间的工作,更新模态进度表单 (.ShowDialog())。

我已经设法SET来自 BW DoWork / ProgressChanged 事件的主要表单属性值,甚至调用表单的方法(在反射对象 http://www.switchonthecode.com/tutorials/csharp-tutorial-using-reflection-to-get-object-information 的帮助下)。

我唯一不知道怎么做就是GET主窗体的控件属性返回给BW线程。

【问题讨论】:

  • 你能显示一些代码吗?反射可能不是该工作的正确解决方案,您可能只需要 InvokeRequired 检查。

标签: c# winforms multithreading reflection backgroundworker


【解决方案1】:

好吧,Reflection API 中的所有 Set 方法都有一个对应的 Get 方法,所以示例中的代码可能是:

MyObject myObjectInstance = new MyObject();
System.Reflection.FieldInfo[] fieldInfo = myObjectType.GetFields();
string strValue = string.Empty;
int intValue = 0;
object objValue = null;

foreach (System.Reflection.FieldInfo info in fieldInfo)
{
   switch (info.Name)
   {
      case "myStringField":
         strValue = (string)info.GetValue(myObjectInstance);
        break;
      case "myIntField":
        intValue = (int)info.GetValue(myObjectInstance);
        break;
     case "myObjectField":
        objValue = info.GetValue(myObjectInstance);
        break;
}

但是,如果您有很多属性,这是获取/设置单个值的低效方法,因此您可以使用 GetField 方法,如下所示:

myType = myObjectInstance.GetType();
strValue = (string)myType.GetField("myStringField").GetValue(myObjectInstance);
intValue = (int)myType.GetField("myIntField").GetValue(myObjectInstance);
objValue = myType.GetField("myObjectField").GetValue(myObjectInstance);

还有一点,Reflection 是一个很棒的工具,但要付出一定的代价。您的代码可维护性较差(毕竟,您使用字符串作为字段名称)并且性能受到严重损害。我的底线是尽可能避免反射,所以请先尝试寻找替代解决方案。

【讨论】:

  • GetField 方法线程安全吗?因为真正的问题是将返回的值传回BackgroundWorker线程?
  • 使用反射并不比使用等效对象更安全,所以如果你有没有反射的竞争条件,它们不会因此而消失。请显示一些代码,因为我认为您根本不需要反射来实现您描述的场景。
猜你喜欢
  • 2012-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-13
相关资源
最近更新 更多