Использование BackGroundWorker для многопоточного вызова действий GUI на элементах управления Winforms? - PullRequest
1 голос
/ 16 ноября 2010

Вдохновленный моим собственным опытом работы с многопоточными приложениями Winforms, а также такими вопросами, как

Я пришел к очень простому шаблону, правильность которого я хотел бы проверить.

По сути, я создаю (и работаю на протяжении всей жизни приложения) BGW, единственной целью которого является синхронизация запросов на вызов.Подумайте:

public MainForm()
{
    InitializeComponent();
    InitInvocationSyncWorker();
}

private void InitInvocationSyncWorker()
{
    InvocationSync_Worker.RunWorkerAsync();
}

private void InvocationSync_Worker_DoWork(object sender, DoWorkEventArgs e)
{
    Thread.Sleep(Timeout.Infinite);
}

void InvokeViaSyncWorker(Action guiAction)
{
    InvocationSync_Worker.ReportProgress(0, guiAction);
}

private void InvocationSync_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    if (IsDisposed) return; //we're in the GUI thread now, so no race condition right?

    var action = (Action) e.UserState;
    action();
}

public void SomeMethodCalledFromAnyThread() //Sample usage
{
    InvokeViaSyncWorker(() => MyTextBox.Text = "Hello from another thread!"));    
}

Конечно, это не самый экономичный из подходов (поддержание потока таким, как этот), но если он работает, и я ничего не пропустил, он, безусловно, самый простой, который я видел.

Обратная связь высоко ценится!

1 Ответ

6 голосов
/ 16 ноября 2010

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

private readonly SynchronizationContext _syncContext;

public MainForm()
{
    InitializeComponent();

    _syncContext = SynchronizationContext.Current;
}

void InvokeViaSyncContext(Action uiAction)
{
    _syncContext.Post(o =>
    {
        if (IsHandleCreated && !IsDisposed) uiAction();
    }, null);
}

public void SomeMethodCalledFromAnyThread() //Sample usage
{
    InvokeViaSyncContext(() => MyTextBox.Text = "Hello from another thread!"));    
}
...