Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 GUI поток виснет при запуске другого потока  [new]
jenya7
Member

Откуда:
Сообщений: 1428
есть функция
private async Task Discover()
{
    int timeout = 0;

    for (byte i = 1; i < range; i++)
    {
        timeout = 0;
        sens_data[2] = i;

       net_udp_socket.Send(sens_data, TextBoxRemoteIP.Text, port);

        Invoke((MethodInvoker)async delegate
        {
            while (udp_msg_rx_ok == 0)
            {
                Thread.Sleep(1);
                timeout++;
                if (timeout >= 1000)
                {
                     RichTextBoxNetReceive.AppendText("ID " + i.ToString() + " timeout\n");
                      break;
                 }
            }

             if (udp_msg_rx_ok == 1)
             {
                   udp_msg_rx_ok = 0;

                  RichTextBoxNetReceive.AppendText("ID " + i.ToString() + " discovered\n");
              }
        });

        Application.DoEvents();
    }
}

запускаю в отдельном потоке
Task.Run(() => Discover());


И все виснет. Тут по идее должно быть что то близкое к секунде
Thread.Sleep(1);
timeout++;
if (timeout >= 1000)

на самом деле в разы больше. и текст RichTextBoxNetReceive печатается с опозданием и сразу несколько строк.
1 ноя 21, 17:13    [22391108]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22584
Так ты же Thread.Sleep выполняешь в потоке GUI - чего б ему не виснуть?
1 ноя 21, 19:09    [22391153]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
pation
Member

Откуда: Москва
Сообщений: 4512
jenya7,

тот кто использует таски - орёл,
а тот кто использует трэды - баклан
2 ноя 21, 03:52    [22391228]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
jenya7
Member

Откуда:
Сообщений: 1428
Shocker.Pro
Так ты же Thread.Sleep выполняешь в потоке GUI - чего б ему не виснуть?

а как мне подождать готовности данных? можно выполнить Sleep в этом потоке? я могу поставить в while Application.DoEvents() и тогда все в порядке но это решение так себе.

Сообщение было отредактировано: 2 ноя 21, 09:34
2 ноя 21, 09:32    [22391254]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
jenya7
Member

Откуда:
Сообщений: 1428
pation
jenya7,

тот кто использует таски - орёл,
а тот кто использует трэды - баклан

с таском такая же ситуация
2 ноя 21, 09:35    [22391255]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22584
Зачем ты вообще выполняешь цикл ожидания в Invoke? Ты с тем же успехом можешь выполнять вот этот же код без всякого Task.Run(() => Discover()); - будет абсолютно то же самое
2 ноя 21, 09:43    [22391259]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22584
Ты смысл Invoke в принципе понимаешь?
2 ноя 21, 09:43    [22391260]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
jenya7
Member

Откуда:
Сообщений: 1428
Shocker.Pro
Зачем ты вообще выполняешь цикл ожидания в Invoke? Ты с тем же успехом можешь выполнять вот этот же код без всякого Task.Run(() => Discover()); - будет абсолютно то же самое

без Invoke при обращении к GUI - RichTextBoxNetReceive.AppendText("ID " + i.ToString() + " timeout\n"); я получаю - cross thread exception
а как без while?

Сообщение было отредактировано: 2 ноя 21, 09:59
2 ноя 21, 09:56    [22391263]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22584
jenya7
без Invoke при обращении к GUI
само собой. обновлять GUI нужно в потоке GUI. Но зачем у тебя цикл внутри Invoke? я об этом спрашивал. Зачем ты вообще запускаешь этот код в отдельной таске, чтобы потом его выполнять в потоке GUI?

Сообщение было отредактировано: 2 ноя 21, 10:03
2 ноя 21, 10:02    [22391265]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
jenya7
Member

Откуда:
Сообщений: 1428
Shocker.Pro
jenya7
без Invoke при обращении к GUI
само собой. обновлять GUI нужно в потоке GUI. Но зачем у тебя цикл внутри Invoke? я об этом спрашивал. Зачем ты вообще запускаешь этот код в отдельной таске, чтобы потом его выполнять в потоке GUI?

в GUI я только высвечиваю сообщения. не ждать же окончания таска а потом вывалить все сообщения в GUI.

может так - вместо while
await Task.Run(() => WaitRxFlagReady());


private int WaitRxFlagReady()
{
       int timeout = 0;

       while (udp_msg_rx_ok == 0)
       {
                Thread.Sleep(1);
                timeout++;
                if (timeout >= 100)
                {
                    return 0;
                }
       }

     return 1;
}


Сообщение было отредактировано: 2 ноя 21, 10:19
2 ноя 21, 10:09    [22391267]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
jenya7
Member

Откуда:
Сообщений: 1428
мда. чтож это получается - Thread.Sleep(1); всегда выполнится в потоке GUI? нельзя это делать в другом потоке?
2 ноя 21, 10:26    [22391274]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22584
jenya7
в GUI я только высвечиваю сообщения.
нет, в GUI у тебя весь внутренний цикл, включая Thread.Sleep

jenya7
Thread.Sleep(1); всегда выполнится в потоке GUI?
Где ты его разместил, там он и выполняется, в данном случае ты его разместил в потоке GUI
2 ноя 21, 11:43    [22391285]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4283
Task.Delay, в чем проблема? Есть еще Dispatcher.Yeald, как вариант, чтоб вернуться в контекст синхронизации.
2 ноя 21, 22:54    [22391458]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 22584
Roman Mejtes
Task.Delay, в чем проблема?
Task.Delay на одну миллисекунду? Смысл? Там и Thread.Sleep-то не особо нужен. Пока ТС не поймет, что такое Invoke, и не вынесет цикл за его пределы, у него все будет тормозить, что с Task.Delay, что без
2 ноя 21, 23:46    [22391462]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
jenya7
Member

Откуда:
Сообщений: 1428
Shocker.Pro
Roman Mejtes
Task.Delay, в чем проблема?
Task.Delay на одну миллисекунду? Смысл? Там и Thread.Sleep-то не особо нужен. Пока ТС не поймет, что такое Invoke, и не вынесет цикл за его пределы, у него все будет тормозить, что с Task.Delay, что без


сделал так
while (udp_msg_rx_ok == 0)
{
     Thread.Sleep(1);
     timeout++;
     if (timeout >= 100)
     {
         Invoke((MethodInvoker)async delegate
          {
                 RichTextBoxNetReceive.AppendText("ID " + i.ToString() + " timeout\n");
         });
         break;
    }
}

ничего не изменилось.
единственное решение которое я смог придумать
private void timerMsCounter_Tick(object sender, EventArgs e)
{
     ms_counter++;
}
3 ноя 21, 09:52    [22391514]     Ответить | Цитировать Сообщить модератору
 Re: GUI поток виснет при запуске другого потока  [new]
pation
Member

Откуда: Москва
Сообщений: 4512
jenya7,

как у тебя вообще получается, что и soket-ы и UI находятся в одном проекте?
я уж не говорю, что в одном классе
и молчу о том, что даже в одном методе
используй single responsibility и сразу поймёшь проблему и способы её решения
9 ноя 21, 18:22    [22393787]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить