Реализуется приложение в котором класс выполняет фоновую обработку задачи.
Когда требуется остановить обработку, отправляется команда на остановку.
Метод создает отдельный фоновый поток в классе, который должен дождаться остановки обработки,
и сгенерировать Событие. Когда событие выполняется, функция-обработчик в главной форме
может получить доступ к простым и сложным типап(int, List), но при попытке изменить свойство
любого элемента формы возникает исключение.
Вызывает исключение: labelStatus.Text = "Остановлен"; где labelStatus System.Windows.Forms.Label
>>>Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'labelStatus' не из того потока, в котором он был создан.
Не вызывает исключение: list.Add("S2"); где List list = new List();
Если не запускать фоновый поток, то исключение не появляется, но такой вариант не приемлем
Как решить проблему доступа к элементам, для сигнализации состояния пользователю?
Ссылка на проект:
https://yadi.sk/d/A51T1HAlgqxU2
Код листинг:
Класс ClassWithEvent
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace EventFromDifferentThread
{
class ClassWithEvent
{
//Thread
Thread thrStop;
public event EventHandler ThresholdReached;
public ClassWithEvent()
{
}
public void Stop()
{
thrStop = new Thread(new ThreadStart(SubStop));
thrStop.Start();
}
private void SubStop()
{
//Sleep 5 Sec
Thread.Sleep(5000);
//Action Event
EventArgs e = new EventArgs();
OnThresholdReached(e);
}
protected virtual void OnThresholdReached(EventArgs e)
{
EventHandler handler = ThresholdReached;
if (handler != null)
{
handler(this, e);
}
}
}
}
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace EventFromDifferentThread
{
public partial class Form1 : Form
{
ClassWithEvent clsWithEvent;
List<string> list = new List<string>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
labelStatus.Text = "Остановлен";
labelStatus.ForeColor = Color.Red;
buttonStart.Enabled = true;
buttonStop.Enabled = false;
list.Clear();
list.Add("S1");
}
private void buttonStart_Click(object sender, EventArgs e)
{
labelStatus.Text = "Работает";
labelStatus.ForeColor = Color.Green;
buttonStart.Enabled = false;
buttonStop.Enabled = true;
//Init
clsWithEvent = new ClassWithEvent();
//Add Event
clsWithEvent.ThresholdReached += frmStop;
}
private void frmStop(object sender, EventArgs e)
{
//здесь нет ошибки, все ок
list.Add("S2");
//Здесь ошибка
labelStatus.Text = "Остановлен";
labelStatus.ForeColor = Color.Red;
buttonStart.Enabled = true;
buttonStop.Enabled = false;
}
private void buttonStop_Click(object sender, EventArgs e)
{
//Stop
clsWithEvent.Stop();
}
}
}