这更多是出于个人好奇/兴趣,而不是我试图解决的特定问题。
假设您有一个程序正在对用户提供的信息(例如搜索字符串)执行某些操作,这些信息会随着用户键入而更改。假设您想要向用户显示与他们在任何给定时间键入的内容最相关的信息。
如果线程确实可以中止,我们可以简单地根据最后更改的搜索字符串运行一个线程,并取消任何先前正在进行的线程。
现在普遍接受的最佳做法是在用户键入时使用延迟计时器,该计时器会在启动操作之前等待 0.5 到 1 秒。我希望很明显,从理论上讲,这不是一个理想解决方案(任何类型的人为延迟都会造成永远无法克服的人为瓶颈,即使只有 0.5 秒)。
此外,今天的最佳实践还指出,任何后续操作都应等待前一个操作完成后再执行。在我们无法中止操作的世界中,这是有道理的,但同样,从理论上讲,这远非理想。想象一下,用户键入一个字符并暂停足够长的时间以便操作开始。假设执行此操作需要 10 秒。用户现在被迫等待不可接受的时间才能看到他/她的查询结果。
对此的一个(不理想的)解决方法是同时执行多个操作,假设这样做是安全的,但这仍然会导致性能显着降低。
所以我只是想知道人们对此的想法,至少是针对 .NET 的,以及自从我上次研究以来该领域是否有任何我应该了解的新发展(也许是并行库?)。我也很想知道是否有任何其他语言/框架可以比 .NET 更好地处理这种细粒度的操作控制。
干杯。
This is more out of personal curiosity/interest than a specific problem I'm trying to solve.
Suppose you have a program that is performing some operation on user-supplied information (such as a search string) that changes as the user types it. Suppose that you want to show the user the most relevant information for what they've typed at any given time.
If threads were really abortable, we could simply have one thread running based on the last-changed search string, and cancel any previous threads that were in progress.
Now the generally accepted best practice for doing this today is to use a delay timer as the user types, which waits for .5 to 1 second before initiating the operation. I hope it's obvious enough that this isn't an ideal solution, theoretically speaking (any kind of artificial delay imposes an artificial bottleneck that can never be overcome, even if it is only 0.5 seconds).
Furthermore, today's best practice goes on to state that any subsequent operations should wait for the previous one to complete before executing. In a world where we can't abort operations, this makes sense, but again, theoretically speaking this is far from ideal. Imagine the user types a single character and pauses just long enough for the operation to begin. Suppose that this operation takes 10 seconds to execute. The user is now forced to wait an unacceptable amount of time before the results of his/her query are visible.
An (unideal) workaround to this would be to have multiple operations executing concurrently, presuming it is safe to do so, but this would still result in significantly reduced performance.
So I'm just wondering people's thoughts on this, specific to .NET at least, and whether there are any new developments in this area since I last researched it that I should know about (parallel libraries perhaps?). I'd also be curious to know if any other languages/frameworks can handle this sort of fine-grained control of operations better than .NET can.
Cheers.
发布评论
评论(4)
您应该查看 任务.NET 4 中的并行库和新的取消模型。任务可以同时运行并且可以安全地取消它们。它看起来很适合您的需要。
You should have a look at the Task Parallel Library in .NET 4 and the new cancellation model. Tasks can be run concurrently and it is safe to cancel them. It looks like a good fit for what you need.
通过 .Net 4 对并行编程的增强,例如TPL 和 取消 正如 Mark Byers 提到的。 “永远不要中止线程!除非你确切地知道你在做什么......即使如此也不要。”值得庆幸的是,规则已经放松。
另一个允许更“组合”方法的工具是 Reactive Extensions for .NET (Rx )。从项目的主页..
他们最近发布了动手实验室...
使用 .NET 的响应式扩展来解决异步问题
...其中包括一个解决方案,在时间上奇怪的巧合中,解决了您的示例... “假设您想向用户显示与他们在任何给定时间输入的内容最相关的信息。”......并且需要取消/中止/停止正在进行的任务。
实验室简介...
按照出色的分步操作,最终的解决方案是......
享受吧。
With .Net 4's enhancements for Parallel Programming like the TPL and cancellation as mentioned by Mark Byers. The "Never abort a thread ! Unless you know exactly what you are doing...Even so don't." rule has thankfully been relaxed.
Another tool that allows a more "compositional" approach is Reactive Extensions for .NET (Rx). From the project's home page..
They recently released a Hands-on-Lab....
Curing the asynchronous blues with the Reactive Extensions for .NET
...that includes a solution that, in a odd coincidence of timing, addresses your example... "Suppose that you want to show the user the most relevant information for what they've typed at any given time."..and the need cancel/abort/stop a task in progress.
In brief from the Lab...
Following an excellent step-by-step the resulting solution is...
Enjoy.
基本上,中止任务的干净方法是很好地要求它,然后让它优雅地自行关闭。这可以是一个标志、一个取消令牌(例如并行扩展)或类似的东西。
这仅在您控制任务时有效 - 或者当它已经被编程为执行此操作时 - 但它在很多情况下都很有用。
一般来说,我不同意“等待上一个操作完成后再执行下一个操作”。当然,这取决于操作 - 但如果您可以并行运行两个操作,可以防止第一个操作的完成造成混乱,并且不介意第一个操作继续运行直到它注意到您刚刚根据此答案的第一段设置的“请停止”标志,就可以了。但这在很大程度上取决于具体情况。
Basically, the clean way to abort a task is to ask it to nicely, and then let it shut itself down gracefully. That could be with a flag, a cancellation token (e.g. Parallel Extensions) or anything like that.
This only works when you're in control of the task - or when it's already programmed to do this - but it's useful in a large number of situations.
I don't agree with the "wait for the previous operation to complete before executing the next one" in general. It depends on the operation, of course - but if you can run two operations in parallel, can prevent the completion of the first one from messing things up, and don't mind the first one continuing to run until it notices the "stop please" flag you've just set as per the first paragraph of this answer, that's fine. It depends heavily on the situation though.
仅仅因为您不应该滥用 Thread.Abort() 并不意味着您不能取消后台线程中的操作。
诀窍是让后台线程干净地退出,而不是意外退出。
Just because you shouldn't abuse
Thread.Abort()
doesn't mean you can't cancel an operation in a background thread.The trick is to let your background thread exit cleanly, not unexpectedly.