创建取消方案
我有一个可以分析源代码的程序。 它可以递归地遍历一个目录来查找所有项目,然后递归地遍历项目来查找所有源代码。
我想创建一个取消进程按钮,它允许用户停止代码解析。 我在后台工作人员中运行代码解析。 我希望能够观看取消事件。
问题是弄清楚如何编辑我的代码,以便它能够检查该项目并返回到 GUI。 解析过程深入到多种方法。
在一个小得多的进程中,我成功地使用了一个线程安全的单例,它有一个布尔值,表示是否已请求取消,并停止正在运行的循环。
将此取消请求处理到我的代码中的最佳方法是什么?
编辑:这是一个想法,灵感来自约翰·桑德斯的回答。
如果我在处理线程中运行一个后台线程来监视 Cancel Singleton 的更改,然后从该进程中抛出异常,会怎么样? 这看起来像是一个好的做法吗?这并不按预期工作
编辑2:约翰·桑德斯的答案似乎是目前最好的。 当单例现在为 true 时,我将抛出我自己的异常。 我将等待看看是否提出其他解决方案
I have a program that will analyzes source code. It can recursively go through a directory to find all projects, and then recursively go through the project to find all source code.
I want to create a cancel process button, which allows the user to stop the code parsing. I run the code parsing in a background worker. I want to be able to watch for the cancel event.
The problem is figuring out how to edit my code so that it will go and check that item and return back to the GUI. The parsing process goes several methods deep.
In a much smaller process, I successfully use a thread-safe singleton that has a bool that says whether or not a cancel has been requested, and stop the loop where it is running.
What would be the best way of working this cancel request into my code?
EDIT: Here is an idea, inspired by John Saunders' answer.
What if I run a background thread in my processing thread that watches for the Cancel Singleton to change, and then throw an exception from that process? Does this seem like good practice? This does not work as intended
EDIT 2: John Saunders' answer seems to be the best for now. I will just throw my own exception when the Singleton is true for now. I'll wait to see if any other solutions are proposed
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Thread.Abort 是一个坏主意,因为它会在任意点中断线程 - 可能会在您最不希望被中断的地方中断它。
设置一个被取消的线程看到的标志。 在每次操作开始时进行检查。 这个想法是确定代码中可以安全停止的位置,并仅在这些点检查标志。
您可能会发现在这些点抛出异常很有用。 该异常应该是在到达代码和 UI 之间的边界之前不会被代码捕获的异常。 那时,您的代码将简单地返回。
Thread.Abort is a bad idea, as it interrupts the thread at an arbitrary point - probably interrupts it where you'd least like to be interrupted.
Set a flag that it seen by the thread being cancelled. Check it at the beginning of each operation. The idea would be to identify places in the code where it is safe to stop, and to check the flag at only those points.
You may find it useful to throw an exception at those points. The exception should be one that is not caught by your code until it reaches the boundary between your code and the UI. At that point, your code would simply return.
您可以在后台工作线程上使用 Thread.Abort() 函数。 这会抛出一个 ThreadAbortException 异常,您可以在任何方法中捕获该异常,但会在 catch 块末尾自动重新抛出该异常。
所有
finally
块也将被执行。You could use the
Thread.Abort()
function on your background worker thread. This throws aThreadAbortException
which you can catch in any of your methods but which will atomatically be rethrown at the end of thecatch
blocks.Also all
finally
-blocks will be executed.听起来您正在使用 .NET backgroundworker 类。 我认为您可以将对象参数传递到 RunWorkerAsync 方法中,然后 DoWork 事件处理程序参数中的后台线程可以访问该方法。
然后,您可以在 UI 线程中修改该对象(例如更新布尔取消属性)并定期从后台进程中检查它。
It sounds like you're using the .NET backgroundworker class. I think you can pass a object parameter into the RunWorkerAsync method which then becomes accessible to the background thread in the DoWork event handler argument.
You could then modify that object in the UI thread (for example update a boolean cancel property) and periodically check on it from your background process.
有多种方法可以对线程操作执行取消; 所有这些都涉及定期检查标志或其他值以确定线程是否应该继续操作。
我不建议为此功能抛出异常。 首先,取消并不是特殊情况,其次,对于您想要实现的目标来说,取消是多余的。
相反,您可以使用简单的线程安全布尔标志作为可从任何线程访问的类的静态成员,或者使用同步对象,例如命名的 互斥体。 然后,向同步对象发出信号将允许线程知道它必须取消。
There are various ways to perform a cancel on threaded operations; all of which involve the periodic checking of a flag or other value to determine if the thread should continue operating or not.
I would not recommend throwing exceptions for this feature. First of all, cancelling is not an exceptional circumstance, and second, it's overkill for what you're trying to implement.
Instead, you could use a simple, thread-safe boolean flag as a static member of a class accessible from any thread, or use a synchronization object such as a named Mutex. Signalling the synchronization object would then allow the thread to know it must cancel.