简体   繁体   English

如何在没有“函数求值要求所有线程都运行”的情况下在后台调用方法

[英]How can I call a method in the background without “The function evaluation requires all threads to run”

So I have this Windows Form Application of a restaurant where I have a module of table Selection and it's going to be used by at least 4 waiters. 因此,我在一家餐馆的Windows窗体应用程序中拥有一个表选择模块,该表将至少由4个服务员使用。

It makes sense that I need to Sync the software when a Table is Set Occupied. 在设置表时需要Sync软件,这很有意义。 My method, called RefreshApp , works like a charm, at least for my needs. 我的方法称为RefreshApp ,至少可以满足我的需要,就像一个魅力一样。 The problem reside in that it can only be successfully called here: 问题在于只能在此处成功调用它:

  private void loadTables() { // Some load tables code... RefreshApp(); } 

Put the method in here and it will run perfectly, just 1 time... thats my problem, I need to refresh it every once in a while, so I tried in a BackGroundWorker: 将方法放到这里,它将完美运行,只需1次...这就是我的问题,我需要不时刷新一下,因此我在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(); } } 

But if I run the code there I get “The function evaluation requires all threads to run”, and if I use the code in a Button_click method to test it in the form manually it give me the same error. 但是,如果我在其中运行代码,则会得到“函数评估需要运行所有线程”,并且如果我在Button_click方法中使用该代码以手动形式对其进行测试,则会产生相同的错误。

 private void btn_Refresh_Click(object sender, EventArgs e) { RefreshApp(); } 

So my Question is, How can I call RefreshApp method in a certain amount of time in background without this kind of error? 所以我的问题是,如何在后台的一定时间内调用RefreshApp方法而不会出现此类错误?

Here is the code for reference (bear in mind that this method already work as needed): 这是供参考的代码(请记住,此方法已根据需要工作):

 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; } } 

I don't understand the error, but you should not access WinForms Controls from different thread than the main (pumping messages). 我不理解该错误,但您不应从不同于主线程的其他线程(抽出消息)访问WinForms控件。 You can use Timer (event will be called in main thread after getting WM_TIMER message). 您可以使用Timer(获取WM_TIMER消息后将在主线程中调用事件)。

You simply cannot call RefreshApp from BackgroundWorker (on any thread except the main). 您根本无法从BackgroundWorker(在除main之外的任何线程上)调用RefreshApp。

NOTE: I was refering to System.Windows.Forms.Timer (not System.Threading.Timer ) 注意:我指的是System.Windows.Forms.Timer (不是System.Threading.Timer
NOTE2: Using Control.Invoke() (InvokeRequired, BeginInvoke, EndInvoke) is another option but Timer was ideal when I saw the code with StopWatch. 注意2:使用Control.Invoke()(InvokeRequired,BeginInvoke,EndInvoke)是另一个选择,但是当我用StopWatch看到代码时,Timer是理想的选择。

This is not technically a case of concurrency , because you just moved the code from the main thread to another. 从技术上讲,这不是concurrency的情况,因为您只是将代码从主线程移到了另一个线程。 To make it work, you should invoke the RefreshApp method on the main thread: 为了使其工作,您应该在主线程上调用RefreshApp方法:

this.Invoke(RefreshApp);  // `this` being your Form

I think the error you get is irrelevant here, but if you want that fixed too: did you place a condition on one of your beakpoints? 我认为您在这里得到的错误是无关紧要的,但是如果您也想解决该错误:您是否在一个喙上设置了条件? That's the problem. 那就是问题所在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 功能评估需要运行所有线程 - The function evaluation requires all threads to run 什么是 function 评估需要所有线程运行? - What is the function evaluation requires all threads to run? 调试期间的 Visual Studio:function 评估需要所有线程运行 - Visual Studio during Debugging: The function evaluation requires all threads to run 懒 <T> :“功能评估需要所有线程运行” - Lazy<T>: “The function evaluation requires all threads to run” 虚拟列表 <T> :“功能评估需要所有线程运行” - virtual List<T> :“The function evaluation requires all threads to run” 使用 Cosmos ExecuteQuery 查询 azure 表存储时,为什么会出现“function 评估需要所有线程运行”? - Why do i get "The function evaluation requires all threads to run" when querying an azure table storage with Cosmos ExecuteQuery? VS2015 Watch LINQ var错误:函数评估需要运行所有线程 - VS2015 Watch LINQ var Error: The function evaluation requires all threads to run EntityFramework中的SaveChanges()不保存更改。 显示“函数评估要求所有线程都运行” - SaveChanges() in EntityFramework not saving changes. Showing “The function evaluation requires all threads to run” ASP.NET MVC或更多VS调试问题-EF / Sql函数评估要求所有线程都运行[保持] - ASP.NET MVC or more of a VS debugging issue - EF/ Sql The function evaluation requires all threads to run [on hold] 调用加载函数时可以在后台进程中运行Outlook附加方法吗? - Can i run outlook add-on method in background process when load function call?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM