我怎么能在后台调用一个方法没有“函数评估需要所有线程运行”
本文关键字:评估 函数 运行 线程 方法 调用 后台 怎么能 一个 | 更新日期: 2023-09-27 18:14:54
我有一个餐厅的Windows窗体应用程序,我有一个表选择模块,它将被至少4个服务员使用。
当表被占用时,我需要Sync
软件是有意义的。我的方法,叫做RefreshApp
,至少对我的需求来说,效果很好。问题在于它只能在这里被成功调用:
private void loadTables() { // Some load tables code... RefreshApp(); }
把方法放在这里,它会完美地运行,只要一次…这是我的问题,我需要刷新它每隔一段时间,所以我尝试在一个BackGroundWorker:
private void bgWorker_DoWork(object sender, DoWorkEventArgs e) { while (true) { Thread.Sleep(100); if (_stopwatch.Elapsed >= TimeSpan.FromSeconds(Constants.refreshTime) && Constants.alreadyWorking == false) { Constants.alreadyWorking = true; RefreshApp(); // Restart the stopwatch for next sync event _stopwatch.Restart(); } }
但是如果我在那里运行代码,我得到"函数评估需要所有线程运行",如果我在Button_click方法中使用代码以手动形式测试它,它会给我同样的错误。
private void btn_Refresh_Click(object sender, EventArgs e) { RefreshApp(); }
所以我的问题是,我如何在后台调用RefreshApp
方法在一定的时间没有这种错误?
private void RefreshApp() { SqlDataReader reader = sqlCommandGetTables.ExecuteReader(); // foreach PictureBox representation of a table, get db value, compare, assign table state foreach (PictureBox item in from d in group_Layout.Controls.OfType<PictureBox>().Reverse() select d) { if (item.Name == "DMPS_Layout") continue; reader.Read(); //if the item.Text property equals database value [mesa1], assign image if (item.Text == reader.GetSqlValue(1).ToString() && Int32.Parse(reader.GetValue(0).ToString()) == Constants.numMesaEmpty) item.Image = Properties.Resources.mesaEmpty; if (item.Text == reader.GetSqlValue(1).ToString() && Int32.Parse(reader.GetValue(0).ToString()) == Constants.numMesaBusy) item.Image = Properties.Resources.mesaBusy; if (item.Text == reader.GetSqlValue(1).ToString() && Int32.Parse(reader.GetValue(0).ToString()) == Constants.numMesaUnavailable) item.Image = Properties.Resources.mesaUnavailable; } }
我不明白这个错误,但是你不应该从不同的线程访问WinForms控件,而不是主线程(泵消息)。你可以使用定时器(事件将在主线程中调用后获得WM_TIMER消息)。
你不能从BackgroundWorker中调用refreshpp(除了main线程)。
注:我指的是System.Windows.Forms.Timer
(不是System.Threading.Timer
)
NOTE2:使用Control.Invoke() (invokerequirequired, BeginInvoke, EndInvoke)是另一种选择,但计时器是理想的,当我看到StopWatch的代码。
这在技术上不是concurrency
的情况,因为您只是将代码从主线程移动到另一个。要使它工作,您应该在主线程上调用RefreshApp
方法:
this.Invoke(RefreshApp); // `this` being your Form
我认为你得到的错误是不相关的在这里,但如果你想修复:你把一个条件在你的一个断点?