我有一个用C#编写的windows移动应用程序,它有更多的对话框。我想在触发事件时更新对话框。这是代码:
public void ServerStateChanged()
{
// update the interface
try
{
if (this.Focused)
{
this.noConnectionsLL.Text = this.tcpServer.ClientsCount.ToString();
}
}
catch (Exception exc)
{
}
}
代码工作了几次,但后来我用这个堆栈获得了这个System.NotSupportedException
:at Microsoft.AGL.Common.MISC.HandleAr()rnat System.Windows.Forms.Control.get_Focused()rnat DialTester.Communication.TCPServerView.ServerStateChanged()rnat ...
从哪个线程触发事件有关系吗?因为我不知道问题出在哪里,为什么它工作了几次,然后就崩溃了。
或者下面的lamba方式。在我因使用Control.BeginInvoke而受到批评之前,BeginInvoke是线程安全的,并且是完全异步的(调用会将更新放入UI事件队列)。
public void ServerStateChanged()
{
this.BeginInvoke((Action)(() =>
{
if (this.Focused)
{
this.noConnectionsLL.Text = this.tcpServer.ClientsCount.ToString();
}
}));
}
这可能是一个跨线程的问题。在函数顶部检查this.InvokeRequired
并做出相应的反应肯定会提高函数的安全性。类似这样的东西:
public void ServerStateChanged()
{
if(this.InvokeRequired)
{
this.Invoke(new delegate
{
ServerStateChanged();
}
return;
}
if (this.Focused)
{
this.noConnectionsLL.Text = this.tcpServer.ClientsCount.ToString();
}
}