#c# #user-interface #windows-mobile
#c# #пользовательский интерфейс #windows-mobile
Вопрос:
У меня есть приложение для Windows Mobile, написанное на C #, в котором больше диалоговых окон. Я хочу обновить диалоговое окно при запуске события. Вот код:
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 ...
Имеет ли значение, из какого потока запускается событие? потому что я не могу понять, в чем проблема, почему это работает несколько раз, а затем происходит сбой.
Ответ №1:
Или способом lamba, как показано ниже. И прежде чем меня раскритикуют за использование Control.BeginInvoke, BeginInvoke является потокобезопасным и полностью асинхронным (вызов поместит обновление в очередь событий пользовательского интерфейса).
public void ServerStateChanged()
{
this.BeginInvoke((Action)(() =>
{
if (this.Focused)
{
this.noConnectionsLL.Text = this.tcpServer.ClientsCount.ToString();
}
}));
}
Ответ №2:
Скорее всего, это проблема из разных потоков. Проверка this.InvokeRequired
в верхней части функции и соответствующая реакция определенно улучшили бы безопасность функции. Что-то вроде этого:
public void ServerStateChanged()
{
if(this.InvokeRequired)
{
this.Invoke(new delegate
{
ServerStateChanged();
}
return;
}
if (this.Focused)
{
this.noConnectionsLL.Text = this.tcpServer.ClientsCount.ToString();
}
}