从不同的线程调用

我无法相信它,这在我的其他应用程序中有效,但在这个有类似结构的那个 – 它没有!

public string ListAdd { set { if (listView1.InvokeRequired) { this.Invoke((MethodInvoker)delegate { listView1.Items.Add(value); }); } else { listView1.Items.Add(value); } } } 

我称之为:

  var formz = Form.ActiveForm as Form1; if (formz != null) formz.ListAdd = "asdasdasdasd"; 

如果我从我接收数据包的函数(我想把它放在listView上)通过TCP调用它 – 没有任何事情发生,但如果我在我初始化WinSock的同一个类中调用它 – 它的工作原理。

问题出在哪里?

编辑:我刚刚调试了应用程序,formz在我称之为的地方为null(接收函数)。 为什么它在那里是空的,但在其他任何地方都没有?

我不认为,它会解决你的问题,但你有没有想过使用以下模式来进行调用? 我认为它更具可读性。 创建此扩展方法。

 public static class ControlExtension { public static void ThreadSafeInvoke(this Control control, MethodInvoker method) { if (control != null) { if (control.InvokeRequired) { control.Invoke(method); } else { method.Invoke(); } } } } 

然后你可以像这样执行线程安全的方法调用。

 Form form = new Form(); form.ThreadSafeInvoke(() => form.Text = "ThreadSafeInvoke"); 

或者一次多次通话。

 form.ThreadSafeInvoke(() => { form.Text = "ThreadSafeInvoke"; form.Visible = true; form.WindowState = FormWindowState.Maximized; }); 

UPDATE

所以问题显然是Form.ActiveForm返回null

  1. 通话时没有活动表格。
  2. 该线程无权获取活动表单 – MSDN声明需要UIPermission 。

如果ActiveForm返回null,那么您可能没有活动表单或者它不是Form1类型。 您正在使用“作为Form1”,因此如果您有一个活动的Form2,那么formz将被设置为null。

你能将formz传递给函数而不是调用ActiveForm吗?

检查您是否处于调试模式; 如果是这样,返回的活动表单值将为null。