如何在操作所在的同一线程中取消 NSOperation?
当我取消 NSOperation 时(当用户按下按钮时),从主线程调用取消方法,但显然该操作正在另一个线程中运行。 因此,为了避免更改 _isExecuting 和 _isFinished 时的竞争条件,我认为应该从 NSOperation 所在的同一线程调用取消(或至少其逻辑)。除此之外,当用户取消它时,多个文件会被删除,并且需要时间。因为cancel是从主线程调用的,所以所有的应用程序都会有一段时间没有响应,这很难看。
如何在当前 NSOperation 的同一线程中执行取消代码?
我在 cancel 中尝试了这个(类似于我在 ASIHTTPRequest 中看到的):
if (_operationThread) {
[self performSelector:@selector(cancelOnRequestThread) onThread:_operationThread withObject:nil waitUntilDone:NO];
} else {
[self cancelOnRequestThread];
}
并且 _operationThread 在 start 方法中设置,使用: _operationThread=[NSThread 当前线程];
但这不起作用。
有什么想法或建议吗?
注意:我使用并发操作,所以我使用start而不是main。
非常感谢您的帮助。 里卡多.
When I cancel an NSOperation (when user presses a button) cancel method is called from the main thread, but evidently the operation is running in another thread.
So, to avoid race conditions when I change _isExecuting and _isFinished, I think cancel (or at least its logic) should be called from the same thread that the NSOperation. Apart from that, when user cancels it, several files are deleted and it takes time. Because cancel is called from main thread, all the app becomes unresponsive for a while, which is ugly.
How can I execute cancel code in the same thread that the current NSOperation?
I tried this in cancel (similar to what I saw in ASIHTTPRequest):
if (_operationThread) {
[self performSelector:@selector(cancelOnRequestThread) onThread:_operationThread withObject:nil waitUntilDone:NO];
} else {
[self cancelOnRequestThread];
}
And _operationThread is setted in start method using:
_operationThread=[NSThread currentThread];
But it doesn't work.
Any idea or suggestion?
Note: I use concurrent operations, so I use start instead of main.
Thanks a lot for help.
Ricardo.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从主线程调用 NSOperation 的取消是可以的。 cancel 方法是线程安全的。
这不应该导致主线程发生任何阻塞,因为取消方法本身不应该执行任何工作。如果您覆盖了删除文件等操作的取消方法,那么这是错误的方法。您不应该重写 cancel 方法,而只需在操作的 main 方法内(例如在任何紧密循环内)的常规点检查 isCancelled 方法,然后如果 isCancelled 返回 YES,则尽早从 main 返回,这将取消同一操作线程作为执行的其余部分。
如果您已经按照这种方式实现了它,但仍然遇到性能问题,那么您的操作是否可能根本没有真正在后台线程上运行?例如,如果您已将其添加到 [NSOperationQueue mainQueue] 返回的队列中,那么它实际上在主应用程序线程上运行。
It's fine to call cancel on an NSOperation from the main thread. The cancel method is thread-safe.
That shouldn't cause any blocking on your main thread because the cancel method itself shouldn't be doing any work. If you have overridden the cancel method of your operation to delete files, etc then that is the wrong approach. You shouldn't override the cancel method, instead just check the isCancelled method at regular points within the operation's main method (e.g. inside any tight loops) and then return from main early if isCancelled returns YES, which will then cancel the operation on the same thread as the rest of the execution.
If that's how you've implemented it already and you're still having performance issues, is it possible that your operation is not really running on a background thread at all? For example if you've added it to the queue returned by [NSOperationQueue mainQueue] then that's actually running on the main application thread.