Метод выполняется дважды после вызова


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

У меня есть запущенный фоновый поток, который при появлении запроса отключит кучу флажков в форме, созданной в основном потоке. Для этого мне нужно безопасно пересекать поток, используя invoke и делегат, но я должен делать это неправильно. Итог, когда я проверю это в отладчик я вижу, что он проходит через действие часть кода дважды, если InvokeRequired. Я могу обойти это, заключив действие в скобки с else, и хотя он не будет проходить через else дважды, он все равно попытается пройти через метод снова.

delegate void ManualCurtainShuttoffHandler();
public void ManualCurtainShutoff()
{
    if (InvokeRequired)                                    
    {
        Invoke(new ManualCurtainShuttoffHandler(ManualCurtainShutoff));           
    }
    // ACTION: Disable check boxes
}
Я просто хотел бы знать, почему он проходит через метод два раза. Дайте мне знать, если вам понадобится дополнительная информация, и я буду рад поделиться ею с вами.
2 2

2 ответа:

Только потому, что вы вызываете Invoke, это не останавливает выполнение текущего метода. Быстрое и простое решение состоит в том, чтобы просто return после вызова Invoke:

delegate void ManualCurtainShuttoffHandler();
public void ManualCurtainShutoff()
{
    if (InvokeRequired)                                    
    {
        Invoke(new ManualCurtainShuttoffHandler(ManualCurtainShutoff));           
        return;
    }
    // ACTION: Disable check boxes
}

Это позволит пропустить остальную часть выполнения ManualCurtainShutoff, которая выполняется в фоновом потоке, в то же время продвигая новое выполнение метода в основном потоке.

Invoke приведет к тому, что ваша функция будет вызвана снова в другом потоке (это ее цель). Вы должны добавить возврат после вызова Invoke. Идея заключается в том, что тогда ваша функция будет вызвана снова (это то, что вы хотите), и это время InvokeRequired будет ложным, поэтому ваше действие будет иметь место.

Правка: блин, к тому времени, как я заканчиваю писать, меня уже избили до полусмерти. Ну что ж!