Почему первый BeginInvoke терпит неудачу, когда вторая попытка успешна?Цикл сообщений не отвечает? - PullRequest
1 голос
/ 20 декабря 2011

У меня есть EventHandler для пользовательского Control, который вызывается из фонового потока и делает элемент управления недействительным.Для этого я использую Invoke следующим образом:

void Foo::handleProgressChanged(Object^ sender, EventArgs^ args)
{
    if (InvokeRequired)
    {
        Invoke(gcnew EventHandler(this, &Foo::handleProgressChanged), sender, args);
        return;
    }

    this->UpdateProgress();
    this->Invalidate(true);
}

В некоторых редких случаях вызов Invoke вызывает тупик , хотя цикл сообщений должен работать.Вызов стека основного потока:

ntdll.dll!770c5ca4()    
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll] 
user32.dll!75e6073f() 
System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = -1, int pvLoopData = 0) + 0x3c8 bytes 
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.WinFormsAppContext}) + 0x177 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes    
System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.ApplicationContext context) + 0x18 bytes
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() Line 768 + 0x9 bytes    Basic
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() Line 1444  Basic
Microsoft.VisualBasic.dll!Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String() commandLine = Nothing) Line 491 + 0x7 bytes    Basic
...

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

  • При каких условиях Invoke может блокировать фоновый поток, когда поток пользовательского интерфейса простаивает?
  • Почему второй вызов BeginInvoke успешен, а первый - нет?

Я использую .NET Framework 2 и C ++ / CLIОднако я полагаю, что проблема не зависит от языка.

Редактировать:

Чтобы сделать его более понятным: оригинальный подход работает большую часть времени.Первые события в сеансе обрабатываются как ожидалось.Но позже, особенно когда события происходят часто, он заходит в тупик.

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