[英]Will an item submitted to the main `DispatchQueue` ever interrupt currently executing code on the main thread?
以下代碼用於在后台線程上執行長時間運行的計算:
enum CalculationInterface {
private static var latestKey: AnyObject? // Used to cancel previous calculations when a new one is initiated.
static func output(from input: Input, return: @escaping (Output?) -> ()) {
self.latestKey = EmptyObject()
let key = self.latestKey! // Made to enable capturing `self.latestKey's` value.
DispatchQueue.global().async {
do {
let output = try calculateOutput(from: input, shouldContinue: { key === self.latestKey }) // Function cancels by throwing an error.
DispatchQueue.main.async { if (key === self.latestKey) { `return`(output) } }
} catch {}
}
}
}
這個函數是從主線程調用的,如下所示:
/// Initiates calculation of the output and sets it to the result when finished.
private func recalculateOutput() {
self.output = .calculating // Triggers calculation in-progress animation for user.
CalculationInterface.output(from: input) { self.output = $0 } // Ends animation once set and displays calculated output to user.
}
我想知道是否有可能在主線程運行我的代碼時執行推送到DispatchQueue.main
的閉包。 或者換句話說,在self.output = .calculating
但在self.latestKey
重新設置為新對象之前執行。 如果可以,則可以向用戶顯示陳舊的計算輸出。
我想知道是否有可能在主線程運行我的代碼時執行推送到
DispatchQueue.main
的閉包
不,這是不可能的。 主隊列是串行隊列。 如果代碼在主隊列上運行,則不能運行“其他”主隊列代碼。 您的DispatchQueue.main.async
實際上意味着:“等到在主隊列上運行的所有代碼自然結束,然后在主隊列上運行它。”
另一方面, DispatchQueue.global()
不是串行隊列。 因此,理論上有可能對calculateOutput
兩個調用重疊。 這不是你想要發生的事情; 您希望確保任何正在執行的calculateOutput
實例在另一個實例可以啟動之前完成(並且我們繼續處理latestKey
)。 換句話說,您要確保序列
latestKey
calculateOutput
latestKey
連貫地發生。 確保這一點的方法是將您使用DispatchQueue(label:)
創建的DispatchQueue(label:)
放在一邊,您將始終使用它來運行calculateOutput
。 默認情況下,該隊列將是串行隊列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.