我想知道我的操作是否被取消或正常完成。这是我的代码段:
Command line: -opensource -confirm-license -release -prefix /Users/username/Desktop/dev/pv/paraview_build/install -I /Users/username/Desktop/dev/pv/paraview_build/install/include -L /Users/username/Desktop/dev/pv/paraview_build/install/lib -skip qtconnectivity -skip qtgamepad -skip qtlocation -skip qtmultimedia -skip qtsensors -skip qtserialport -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -nomake examples -nomake tests -no-dbus -qt-libjpeg -qt-pcre -system-zlib -no-openssl -skip qtsvg -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -qt-libpng
executing config test verifyspec
+ cd /Users/username/Desktop/dev/pv/paraview_build/superbuild/qt5/build/config.tests/verifyspec && /Users/username/Desktop/dev/pv/paraview_build/superbuild/qt5/build/qtbase/bin/qmake "CONFIG -= qt debug_and_release app_bundle lib_bundle" "CONFIG += shared warn_off console single_arch" 'QMAKE_LIBDIR += /Users/username/Desktop/dev/pv/paraview_build/install/lib' 'INCLUDEPATH += /Users/username/Desktop/dev/pv/paraview_build/install/include' /Users/username/Desktop/dev/pv/paraview_build/superbuild/qt5/src/qtbase/config.tests/verifyspec
> Project ERROR: QMAKE_MAC_SDK can only contain short-form SDK names (eg. macosx, iphoneos)
后来我有了:
class PacketReceiver {
private let m_executer = OperationQueue()
private var m_operation : Operation?
private func operationFinishedHandler()
{
if let op = m_operation {
if op.isCancelled {
print("Operation cancelled")
} else {
print("Operation finished OK \(op.isCancelled)")
}
}
}
func start()
{
let rxPacketOperation = PacketReceiverOperation()
rxPacketOperation.completionBlock = self.operationFinishedHandler
m_operation = rxPacketOperation
m_executer.addOperation(rxPacketOperation)
}
func cancel()
{
if let op = m_operation {
op.cancel()
}
}
func join()
{
if let op = m_operation {
print("is op cancelled = \(op.isCancelled)")
}
m_executer.waitUntilAllOperationsAreFinished()
if let op = m_operation {
print("is op cancelled = \(op.isCancelled)")
}
}
}
我看到内部let packetReceiver = PacketReceiver()
packetReceiver.start()
packetReceiver.cancel()
packetReceiver.join()
方法join()
的属性设置为true。但是当我在完成的处理程序中检查它时,它是错误的。我想这是预期的行为。但是检查我的操作是否被取消的正确方法是什么?
这是我的操作课:
isCancelled
答案 0 :(得分:1)
由于各种原因(尤其是缺少抢先取消和一般比赛条件),isCancelled
状态不是知道Operation
子类是否成功完成的可靠方法。 (它告诉您是否尝试取消操作,但不告诉基础任务是否成功。)
由于这个原因,我很少使用内置的completionHandler
(无参数),而是通常实现自己的自定义完成处理程序闭包,该闭包提供Result
(或其他任何东西)作为参数。这消除了所有歧义。
或者,在您的情况下,您可以将isPacketReceived
设置为操作的属性,而不是局部变量,然后您可以查看该结果以确定是否已完全接收到数据包,而不是{{ 1}}。
您后来说:
我看到
isCancelled
完成后调用了completionHandler
。
是的,是的。
但是join()
根本就是一个同步方法,这有点让人担心(即您正在呼叫join
)。操作队列的目的是让我们可以为可能耗时的任务采用异步模式,并将其从主线程中删除。在我们等待操作完成时阻塞(特别是如果您是从主线程调用waitUntilAllOperationsAreFinished
的话)似乎无法达到目的。
我鼓励您采用异步模式,只需将操作添加到队列中,然后在其完成处理程序中启动所需的任何内容(无论是默认操作还是您自己的操作)。