Проблема многопоточности Winforms, второй поток не может получить доступ к 1-м основным средствам управления формами

Если вы хотите добавить элемент в последнюю позицию списка, вы можете попробовать: list.insert(END, item)

self.recievingAdress.insert(END, "apple")
7
задан 29 September 2008 в 16:32
поделиться

9 ответов

Вы не можете получить доступ к элементам UI от нескольких потоков.

Один способ решить это состоит в том, чтобы назвать Вызвать метод управления с делегатом в функции, которые используют элементы UI (как окно сообщения). Somethin как:

public delegate void InvokeDelegate();

public void SomeMethod()
{

    button1.Invoke((InvokeDelegate)doUIStuff);


}


void doUIStuff()
{
           MessageBox.Show(this,   
                ex.Message, 
                "Error", 
                MessageBoxButtons.OK, 
                MessageBoxIcon.Error
            );
}
9
ответ дан 6 December 2019 в 07:53
поделиться

для предотвращения исключений перекрестного потока (InvalidOperationException) вот, шаблон кода:

protected delegate void someGuiFunctionDelegate(int iParam);

protected void someGuiFunction(int iParam)
{
    if (this.InvokeRequired)
    {
        someGuiFunctionDelegate dlg = new 
            someGuiFunctionDelegate(this.someGuiFunction);
        this.Invoke(dlg, new object[] { iParam });
        return;
    }

    //do something with the GUI control here
}

я соглашаюсь, что это является раздражающим, но это - артефакт того, что средства управления окнами GUI не ориентированы на многопотоковое исполнение. Исключение может быть выключено с флагом где-нибудь или другим, но не делает этого, поскольку оно может привести к чрезвычайно трудно для нахождения ошибок.

7
ответ дан 6 December 2019 в 07:53
поделиться

Для хранения вещей простыми, можно изучить использование класса BackGroundWorker. Этот класс будет служить основой для обработать Вашу поточную обработку и события уведомления о прогрессе. Ваш поток ui обработает событие прогресса и отобразит сообщение об ошибке, которое Вы пасуете назад.

3
ответ дан 6 December 2019 в 07:53
поделиться

ИЛИ

2
ответ дан 6 December 2019 в 07:53
поделиться

Правило номер один, когда многопоточность - Вы абсолютно, не может коснуться UI от рабочих потоков. Существует много способов реализовать многопоточность, и очень трудно разобраться в нем.

Вот сжатая статья, которая должна выручить Вас - Обновление UI от Вторичного Потока

И вот длинная статья, которая обсуждает всестороннюю поточную обработку - Многопоточность в.NET

1
ответ дан 6 December 2019 в 07:53
поделиться

Вы не должны использовать BeginInvoke, необходимо использовать, Вызывают, затем после того как Вы осознаете, что, можно изучить использование BeginInvoke, если действительно необходимый.

0
ответ дан 6 December 2019 в 07:53
поделиться
'*******************************************************************
' Get a new processor and fire it off on a new thread.
'*******************************************************************
fpProc = New Processor(confTable, paramFile, keyCount)
AddHandler fpProc.LogEntry, AddressOf LogEntry_Handler
Dim myThread As System.Threading.Thread = New System.Threading.Thread(AddressOf fpProc.ProcessEntry)
myThread.Start()

Затем в родительском приложении Вы имеете:

'*************************************************************************
'     Sub: LogEntry_Handler()
'  Author: Ron Savage
'    Date: 08/29/2007
'
' This routine handles the LogEntry events raised by the Processor class
' running in a thread.
'*************************************************************************
Private Sub LogEntry_Handler(ByVal logLevel As Integer, ByVal logMsg As String) Handles fProc.LogEntry
 writeLogMessage(logMsg);
End Sub

Это - то, что я делаю.

0
ответ дан 6 December 2019 в 07:53
поделиться

Проверьте на InvokeRequired

0
ответ дан 6 December 2019 в 07:53
поделиться
..

Я, в сущности, похож на рекурсивный вызов.

public delegate void InvokeDelegate(string errMessage); 

    public void SomeMethod() 
    { 
        doUIStuff("my error message");
    } 


    void doUIStuff(string errMessage) 
    { 
        if (button1.InvokeRequired)
            button1.Invoke((InvokeDelegate)doUIStuff(errMessage)); 
        else
        {
               MessageBox.Show(this,    
                    ex.Message,  
                    errMessage,  
                    MessageBoxButtons.OK,  
                    MessageBoxIcon.Error 
                ); 
        }
    } 
0
ответ дан 6 December 2019 в 07:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: