Я подозреваю, что вы что-то делаете с циклом сообщений Windows и многопоточностью в WinForms. Я не знаю, что это такое, но вот несколько советов:
Вы можете запустить задачу кнопки в backgroundWorker, чтобы сохранить работу вне потока пользовательского интерфейса. Это решает проблему блокировки. Перетащите BackgroundWorker из панели инструментов, поместите его в форму в конструкторе и подключите событие, т. Е .:
.
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
затем переключите ваш код в btManual_Click, чтобы вызвать фонового работника следующим образом:
backgroundWorker1.RunWorkerAsync();
и затем:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Mcount = tty.SomeStupidBlockingFunction(Mcount);
this.BeginInvoke((Action)delegate { txtManual.Text = Mcount.ToString(); });
}
Я пропустил блокировку (tty), потому что я предпочел бы видеть только одно из этих утверждений внутри функции, а не пять из них снаружи. И вместо блокировки на tty я бы создал приватную переменную, подобную этой:
public class MegaAPI
{
private object sync = new object();
public int SomeStupidBlockingFunction(int c)
{
lock (this.sync)
{
Thread.Sleep(800);
return ++c;
}
}
}
Затем все остальные упрощаются, например:
void UIUpdate1()
{
ACount1 = tty.SomeStupidBlockingFunction(ACount1);
this.BeginInvoke((Action)delegate { txtAuto1.Text = ACount1.ToString(); });
}
И поскольку вы не можете запустить фоновый рабочий, пока он еще обрабатывает, вот быстрое и грязное решение: отключите кнопку во время ее работы:
this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
и затем:
private void btManual_Click(object sender, EventArgs e)
{
this.btManual.Enabled = false;
backgroundWorker1.RunWorkerAsync();
}
и
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.btManual.Enabled = true;
}
Поэтому я рекомендую:
- Оставьте один оператор lock ()
внутри функции, нуждающейся в
синхронизация
- Хранить объект блокировки в секрете
- Запустить работу на фоновом рабочем