Что не так с моим InvokeRequied # 2? - PullRequest
3 голосов
/ 20 января 2012

Первая тема: Что не так с моим InvokeRequied

Я последовал ответу, что он порекомендовал его мне, но обнаружил новую проблему.

РезультатНа рисунке ниже показано исключение кросс-потока.

Что не так с моим кодом?

Как решить эту проблему?

enter image description here

1 Ответ

9 голосов
/ 20 января 2012

Согласно MSDN InvokeRequired может вернуть false даже в тех случаях, когда InvokeRequired должно быть true, а именно в том случае, если вы получаете доступ к InvokeRequired до Handle этогоЭлемент управления / форма (или его родитель) создан.

По сути, ваша проверка не завершена, что приводит к полученному результату.

Вам необходимо проверить IsHandleCreated - если это false, вам нужно будет использовать Invoke / BeginInvoke независимо от того, что возвращает InvokeRequired.

[ОБНОВЛЕНИЕ] НО : Обычно это не работает надежно, так как Invoke / BeginInvoke проверяет, какой поток создал Handle, чтобы творить свою магию ... [/ UPDATE]

Только если IsHandleCreated равно true, вы действуете на основе того, что InvokeRequired возвращает - что-то вроде:

if (control.IsHandleCreated)
{
    if (control.InvokeRequired)
    {
        control.BeginInvoke(action);
    }
    else
    {
        action.Invoke();
    }
}
else 
{ 
    // in this case InvokeRequired might lie - you need to make sure that this never happens! 
    throw new Exception ( "Somehow Handle has not yet been created on the UI thread!" );
}

[ОБНОВЛЕНИЕ]

Таким образом, чтобы избежать этой проблемы, важно следующее

Всегда проверяйте, что Handle уже создан ДО первого доступа к потоку, отличному от потока пользовательского интерфейса.

Согласно MSDN вам просто нужно сослаться на control.Handle в потоке пользовательского интерфейса, чтобы принудительно создать его - в вашем коде это должно происходить ПЕРЕД тем, как вы впервые получаете доступ к этому элементу управления / форме из любого потока, который не являетсяпоток пользовательского интерфейса.

[/ UPDATE]

...