Я знаю, что этот вопрос задавался несколько раз, но я не могу понять, почему он так поступает в моей ситуации.
Прежде всего, я немного объясню свою программу.Он подключается к аппаратному устройству через чип FTDI, поэтому он генерирует нам COM через USB.Мои программы запускаются, это интерфейс MDI.При нажатии кнопки «Подключить» открывается окно подключения, аналогичное окну «Добавить устройство» в Windows.Он сканирует все COM на компьютере и пытается подключиться к нему, чтобы сообщить, что это за устройство.После этого пользователь нажимает на устройство, подключается к нему, и открывается дочерняя форма для управления этим устройством.
Итак, моя проблема в том, что у меня много многопоточности.При первом подключении к устройству все работает нормально.Во второй раз он возвращает ошибку операции с несколькими потоками.
Это краткий пример моего кода:
private void ConnectToolStripButton_Click(object sender, EventArgs e)
{
Dialogs.Connect Connect = new Dialogs.Connect();
if (Connect.ShowDialog() == DialogResult.OK)
{
this.Connect(Connect.Connection);
}
}
private void Connect(CommunicationInterfaces.Base Connection)
{
// Set the connection to the one the connect dialog gave us.
Child NewConnection = new Child(Connection);
// Set the parent of the new child and show it.
NewConnection.MdiParent = this;
NewConnection.Show(); // CRASH HERE!
}
Так что он падает на .show () со следующей ошибкой, но только во второй раз, когда я подключаюсь к нему: Cross-thread operation not valid: Control 'Child' accessed from a thread other than the thread it was created on.
Объект-это дочерний объект (имя моей дочерней формы) создается в потоке пользовательского интерфейса, если я не ошибаюсь.Почему это дает мне ошибку межпотоковой операции тогда?Это проблема в моей дочерней форме?
Обновление: Таймер поддержания активности
Так что я смог уточнить проблему чуть больше.Проблема заключается в том, что у меня есть ветка Keep Alive, которая есть в форме моего ребенка.Чтобы объяснить ситуацию: у меня есть соединение, которое необходимо поддерживать в рабочем состоянии, поэтому каждые 500 мс у меня запускается поток для отправки специального заголовка на мое устройство.Это мой код потока активности:
private void Child_Shown(object sender, EventArgs e)
{
this.Connection.DataReceived += DisplayData;
...
}
private void DisplayData(object Sender, byte[] Data)
{
...
CreateFaultBox((FaultBoxes.Base.BoxTypes)Data[1]);
...
}
private void CreateFaultBox(FaultBoxes.Base.BoxTypes BoxType)
{
KeepAliveTimer = new System.Threading.Thread(new System.Threading.ThreadStart(this.KeepAlive));
KeepAliveSwitch = true;
KeepAliveTimer.Start();
...
}
private void KeepAlive()
{
while (Connection != null && KeepAliveSwitch)
{
Console.WriteLine("KEEP ALIVE");
// Keep the connection alive.
Connection.KeepAlive();
// Wait 500ms for the next keep alive.
System.Threading.Thread.Sleep(500);
}
}
Если я удаляю первые 3 строки, поэтому, если я не запускаю поток, он работает без каких-либо отклонений.Конечно, KeepAliveSwitch устанавливается в значение false, когда я закрываю форму, поэтому получение потока поддержки активности прекращается после следующего периода ожидания 500 мс.
Решение
Я изменил поток поддержки активности на фонработник.Работает отлично.Но я не вижу разницы между потоком и фоновым рабочим, не должны ли оба работать одинаково в этом сценарии?