1

Есть реализация класса купюроприемника(dll). Я читаю его статус и хочу на форме выводить его в TextBox. После чтения статуса я хочу вызвать событие в котором и записать в TextBox значение.

public event EventHandler GetStatus;

......

    public async Task StartCommunication()
    {
        await Task.Run(() => StartProccess(token), token);
    }

    private void StartProccess(CancellationToken token)
    {
        byte resultStatus;
        resultStatus = Reset();
        Task.Delay(200);
        resultStatus = SetSequrity();
        while (!token.IsCancellationRequested)
        {
            resultStatus = StatusRequest();
            OnGetStatus(new BillEventArgs(resultStatus));

            Task.Delay(200);
        }
    }

....

protected void OnGetStatus(BillEventArgs e)
        {
            GetStatus?.Invoke(this, e);
        }

На форме делаю так

private async void button11_Click(object sender, EventArgs e)
        {
            bill.GetStatus += Bill_GetStatus;
            await bill.StartCommunication();
        }

        private void Bill_GetStatus(object sender, EventArgs e)
        {
            var eventArg = e as BillEventArgs;
            textBox3.Text = eventArg.Status.ToString();
        }

но при возникновении события вылетает ошибка на строке

textBox3.Text = eventArg.Status.ToString();

System.InvalidOperationException: "Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'textBox3' не из того потока, в котором он был создан

Как правильно организовать доступ к контролам на форме в такой ситуации?

gregor
  • 929
  • Похожий вопрос: https://ru.stackoverflow.com/questions/418461/Работа-с-контролами-из-фонового-потока – Philippe Aug 12 '18 at 13:29
  • @Philippe чем похоже? Там инициатор из UI потока, тут инициатор из не UI потока, – tym32167 Aug 12 '18 at 14:26
  • @tym32167 тут инициатор тоже из UI потока (обратите внимание на StartCommunication) – Pavel Mayorov Aug 12 '18 at 17:43
  • @PavelMayorov хмм, это я пропустил – tym32167 Aug 12 '18 at 17:46
  • @Philippe сорри, поторопился – tym32167 Aug 12 '18 at 17:46
  • @gregor обратите внимание на использование IProgress в ответе по приведенной вам ссылке... – Pavel Mayorov Aug 12 '18 at 17:48
  • @PavelMayorov А разве StartProcess не выполняется в другом потоке? Об этом собственно и говорит ошибка – gregor Aug 12 '18 at 18:17
  • @gregor в упомянутом ответе по ссылке тоже есть код который выполняется в другом потоке. Говорю же, посмотрите как там используется IProgress. – Pavel Mayorov Aug 12 '18 at 18:29

1 Answers1

1

Для доступа к контролу из другого потока можно использовать Form.Invoke() - этот метод выполняет указанный делегат в том потоке, в котором была создана форма. Например, так:

private void Bill_GetStatus(object sender, EventArgs e)
{
    var eventArg = e as BillEventArgs;
    this.Invoke(new MethodInvoker(() =>
    {
        textBox3.Text = eventArg.Status.ToString();
    }));
}
Groxan
  • 1,554