我怎么能在后台调用一个方法没有“函数评估需要所有线程运行”

本文关键字:评估 函数 运行 线程 方法 调用 后台 怎么能 一个 | 更新日期: 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

我认为你得到的错误是不相关的在这里,但如果你想修复:你把一个条件在你的一个断点?