I have a UDP method that waits for a reply using the DispatchQueue using the following code:
DispatchQueue.global(qos: .userInitiated).async {
let server:UDPServer=UDPServer(address:"0.0.0.0", port:5005)
let (data,_,_) = server.recv(1024)
DispatchQueue.main.async {
...
}
}
This works perfectly and sets off a process to wait for my data to come in. What's keeping me up at night is what happens if we never get a reply? server.recv never returns so I cannot see how the process will ever end? Is there a way of giving it a predetermined amount of time to run for?
You don't stop the queue. Instead, when the task that you dispatched starts executing, it needs to check its context and do the right thing (often: nothing) if the context has changed.
So, to stop a work item that has already started, you have to test for cancelations yourself. In Swift, cancel the DispatchWorkItem . In Objective-C, call dispatch_block_cancel on the block you created with dispatch_block_create .
You can't pause / cancel when using a GCD queue. If you need that functionality (and in a lot of general cases even if you don't) you should be using the higher level API - NSOperationQueue .
Dispatch queues are FIFO queues to which your application can submit tasks in the form of block objects. Dispatch queues execute tasks either serially or concurrently. Work submitted to dispatch queues executes on a pool of threads managed by the system.
There is no way to stop or "kill" a DispatchWorkItem
or NSOperation
from outside. There is a cancel()
method, but that merely sets the isCancelled
property of the item or operation to true. This does not stop the execution of the item itself. Ans since recv
is blocking, there is no way to check the isCancelled
flag during execution. This means the answer posted by Vadian unfortunately wouldn't do anything.
According to the Apple docs on NSOperation.cancel
:
This method does not force your operation code to stop.
The same goes for NSOperationQueue.cancelAllOperations
:
Canceling the operations does not automatically remove them from the queue or stop those that are currently executing.
You might think it is possible to drop down to using a raw NSThread
. However, the same principle applies hier. You cannot deterministically kill a thread from the outside.
Possible solution: timeout
The best solution I can think of is to use the timeout feature of the socket. I don't know where UDPServer
comes from, but perhaps it has a built in timeout.
Possible solution: Poor man's timeout (send packet to localhost)
Another option you can try is to send some UDP packets to yourself after a certain time has elapsed. This way, recv
will receive some data, and execution will continue. This could possibly be used as a "poor man's timeout".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With