Диалог не отображается должным образом с .Show, но не хочет блокировать .ShowDialog при многопоточности в C # - PullRequest
2 голосов
/ 16 декабря 2009

У меня есть программа, которая должна подключиться к серверу для сбора некоторых данных. Я запускаю новый поток и выполняю последовательность соединений. В этой последовательности он будет продолжать пытаться подключиться до тех пор, пока не сделает это успешно.

Код для последовательности подключения следующий:

// Code for InitializeConnection
// Our address to our Authentication Server
IPEndPoint authenServerEP = new IPEndPoint(IPAddress.Parse("192.168.1.100"), 8007);

// Connect to the Authentication server
while (!this.connected)
{
    try
    {
        this.sock.Connect(authenServerEP);
        this.connected = true;
    }
    catch (SocketException retryConnectException)
    {
        if (false == retried)
        {
             retried = true;
        }
    }
}  

После того, как я запускаю поток, в родительском / основном потоке я продолжаю цикл и проверяю переменную, объявленную в моей основной форме / диалоге, на предмет того, подключен он или нет.

Код для основного потока выглядит следующим образом:

// Connect to the Authentication Server                             
new Thread(InitializeConnection).Start();
// Loop till connected
while (!this.connected)
{
     if ((true == this.retried) && (false == this.establishingConnectionForm.Visible))
     {
        this.establishingConnectionForm.Show();
     }
}
this.establishingConnectionForm.Dispose();

Если в коде InitilizeConnection он повторяет попытку подключения, потому что не удалось в первый раз, я хотел бы, чтобы он показал новое диалоговое окно / форму, которая позволяет пользователю узнать, что он пытается подключиться. Когда я использую метод .Show () при установленииConnectionForm (в родительском потоке), он вызывает диалог / форму, но не отображается должным образом. Некоторые из инструментов в форме затенены белым, а значок мыши превращается в значок мышления / выполнения работы и не позволяет нажимать на форму и взаимодействовать с ней.

То, что я себе представлял, - это то, что я смогу показать форму и взаимодействовать с ней (т.е. закройте ее, пометив ее буквой «X» в верхнем правом углу), переместить ее и прочее. Когда соединение было установлено, я выходил из цикла while (! This.connected) в основном / родительском потоке, а затем закрывал / удалял установлениеConnectionForm.

Я попытался создать / инициализировать форму в потоке, который выполняет последовательность соединений, но я все еще получаю тот же результат с инструментами в форме, которые затемнены и не могут взаимодействовать с ней. Использование метода .ShowDialog () обеспечивает правильное отображение и позволяет мне взаимодействовать с ним, но я не хочу блокировать, так как у меня нет DialogResult. Я хочу, чтобы форма закрывалась сама собой после установления соединения.

Я ценю, что вы читаете мою ветку и любые ваши комментарии. : D

Ответы [ 3 ]

1 голос
/ 16 декабря 2009

Вы также можете использовать Вручную или Автосброс событий с тайм-аутами для управления интервалами опроса и обновления отображения хода выполнения («подключение», «подключение», «сбой») на каждом интервал ожидания до "установки" события

AutoResetEvent connectEvent = new AutoResetEvent(false);
while (!this.connected)
{
     if (connectEvent.WaitOne()) {
        this.establishingConnectionForm.Show();
     } else {
        this.stilltryingForm.Show();
     }
}

или что-то подобное.

1 голос
/ 16 декабря 2009

Вы не можете выполнить такой цикл в потоке пользовательского интерфейса, он не сможет выполнять такие основные функции, как рисование окон и реагировать на ввод. Не используйте DoEvents (), в результате чего ваш код будет работать без какого-либо пользовательского интерфейса, когда пользователь закроет основную форму. Вы получите ObjectDisposedException, если вам повезет.

Решение состоит в том, чтобы позволить потоку уведомить поток пользовательского интерфейса о том, что у него возникли проблемы с установлением соединения. Вы можете сделать это с помощью события ReportWgress BackgroundWorker's.

1 голос
/ 16 декабря 2009

Не используйте цикл опроса. Вы связываете этот поток в цикле, чтобы он никогда не отправлял никаких событий. Без отправки событий пользовательский интерфейс не работает.

  1. Показать форму подключения с помощью ShowDialog
  2. Перейдите в диалоге в функцию соединения.
  3. В вашей ветке соединения после подключения используйте код следующим образом:

    form.Invoke (новый ThreadStart (делегат () { form.Close (); }));

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...