如何在C#中暂停和恢复foreach循环? [英] How to pause and resume foreach loop in C#?

查看:352
本文介绍了如何在C#中暂停和恢复foreach循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我需要为winform应用程序制作暂停按钮和恢复按钮。

我发现ManualResetEvent是创建它们的简单方法。

是吗?

我在我的源代码中添加了ManualResetEvent但暂停foreach循环无效。

我缺少什么?

请给我建议

谢谢



Hi,
I need to make pause button and resume button for winform application.
And I found ManualResetEvent is easy way to create them.
Is that right?
I added ManualResetEvent in my source code but pausing the foreach loop is not working.
What am I missing?
Please give me advice
Thank you

static ManualResetEvent mr = new ManualResetEvent(true);


       public Form1()
       {
           InitializeComponent();
       }

       private void btn_start_Click(object sender, EventArgs e)
       {
         Thread  _thread = new Thread(work);
           _thread.Start();

       }
       private void work()
       {
           foreach (TreeNode node in treeview1.Nodes)
           {
                   mr.WaitOne();

                   if (node.Checked)
                   {
                      some code
                   }


           }
          
       }

       private void btn_pause_Click(object sender, EventArgs e)
       {
           mr.Reset();
       }

       private void btn_resume_Click(object sender, EventArgs e)
       {
           mr.Set();
       }





我的尝试:



我试过把MenaulResetEvent.waitone();在循环结束时。

但仍然没有工作



What I have tried:

I have tried put the MenaulResetEvent.waitone(); at the end of loop.
But still not working

推荐答案

你的想法非常好。



您缺少与暂停无关但与UI线程相关的一件事。您不应该操纵添加到UI线程中添加到当前运行的UI的对象。您尝试在其他非UI线程中执行此操作,这是错误的跨线程操作。您不能从非UI线程调用与UI相关的任何内容。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:

Control.Invoke()与Control.BeginInvoke()

使用Treeview扫描仪和MD5的问题



另请参阅有关线程的更多参考资料:

主要的.NET事件线程

如何让keydown事件在不同的线程上运行i n vb.net

启用禁用+多线程后控制事件没有触发



除此之外,你应该排除修改状态的可能性以某种随机方式从两个线程控制你。特别是,当循环遍历节点集时,不应直接从UI事件更新节点。结合您的暂停功能,这本身就是非常正确的,它可能会导致一些太复杂的线程同步模式,您应该在理论上非常准确地研究(使用通常的调试方法无法检测到这些问题,根本没有测试方法)。也就是说,我会以整体方式考虑整个问题,并可能考虑对代码进行全面重新设计。在这一刻,我无法提出任何建议,因为我不知道你的最终目标。



再说一遍。永远不要使用 treeview1 btn_pause_Click 等名称或任何其他自动生成的名称。他们违反(好的)Microsoft命名约定(自动代码生成的作者根本没有选择)并且毫无意义。名称应该在语义上合理。您应该使用重构引擎重命名每个自动生成的名称,这很容易。此外,这是一个讨论的问题,但我通常建议不要在设计器中生成任何事件处理程序。为添加此类处理程序而生成的代码很难甚至过时。



-SA
Your idea is quite good.

You are missing one thing unrelated to pausing, but related to UI thread. You should not manipulate objects added to currently running UI added to it in UI thread. You try to do it in your additional non-UI thread, and this is bad cross-thread operation. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke(),
Problem with Treeview Scanner And MD5.

See also more references on threading:
.NET event on main thread,
How to get a keydown event to operate on a different thread in vb.net,
Control events not firing after enable disable + multithreading.

In addition to that, you should exclude the possibilities of modifying the state of your control from two threads in some random manner. In particular, you should not update the Nodes from UI events directly while the loop is traversing the set of nodes. Combined with your pausing feature, which is itself is quite correct, it may lead to a bit too complicated thread synchronization schema you should study theoretically very accurately (such problems are undetectable using the usual debugging method, no testing methods at all). That said, I would consider the whole problem in a holistic manner and probably think about total redesign of your code. At this moment, I cannot advise anything certain, because I don't know your ultimate goals.

One more note. Never ever use names like treeview1, btn_pause_Click or any other auto-generated names. They violate (good) Microsoft naming conventions (authors of automatic code generation simply had no choice) and makes no sense. Names should be semantically sensible. You are supposed to rename every auto-generated name using the refactoring engine, which makes is easy. Also, it's a matter of some discussion, but I usually advice not to generate any event handlers in the designer. The code generated for adding such handlers is ugly and even obsolete.

—SA


这篇关于如何在C#中暂停和恢复foreach循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆