我怎样才能让我的代码等到DispatchQueue中的任务完成?它需要任何CompletionHandler或其他东西吗?
func myFunction() {
var a: Int?
DispatchQueue.main.async {
var b: Int = 3
a = b
}
// wait until the task finishes, then print
print(a) // - this will contain nil, of course, because it
// will execute before the code above
}
我使用Xcode 8.2并在Swift 3中编写。
答案 0 :(得分:161)
使用<ContentDialog
x:Class="MyClass.Views.MyContentDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyClass.Views"
xmlns:controlextensions="using:BSE.UI.Xaml.Controls.Extensions"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
PrimaryButtonText="Button1"
SecondaryButtonText="Button2"
controlextensions:ContentDialog.DialogCancel="{Binding Cancel}"
controlextensions:ContentDialog.CancelableCommandParameter="{Binding}"
controlextensions:ContentDialog.CancelableCommand="{Binding MyCancelableCommand}">
</ContentDialog>
来实现此目的。您可以在群组的namespace MyClass.ViewModels
{
public class MyContentDialogViewModel : ViewModelBase
{
private ICommand m_myCancelableCommand;
private bool m_cancel;
public ICommand MyCancelableCommand=> m_myCancelableCommand ?? (m_myCancelableCommand = new RelayCommand<object>(CancelableSave));
public bool Cancel
{
get
{
return m_cancel;
}
set
{
m_cancel = value;
RaisePropertyChanged("Cancel");
}
}
private void CancelableSave(object obj)
{
Cancel = !ValidateDialog();
}
private bool ValidateDialog()
{
return true// if saving successfull otherwise false
}
}
}
和.vue
来电均衡时收到通知:
DispatchGroup
或者你可以等待(并返回):
enter()
注意:leave()
阻止当前队列(可能是您的主要队列),因此您必须在另一个队列上func myFunction() {
var a: Int?
let group = DispatchGroup()
group.enter()
DispatchQueue.main.async {
a = 1
group.leave()
}
// does not wait. But the code in notify() gets run
// after enter() and leave() calls are balanced
group.notify(queue: .main) {
print(a)
}
}
(如上面的示例代码中所示) )避免死锁。
答案 1 :(得分:20)
在Swift 3中,DispatchQueue
完成一项任务时不需要完成处理程序。
此外,您可以通过不同方式实现目标
一种方法就是这样。
var a: Int?
let queue = DispatchQueue(label: "com.app.queue")
queue.sync {
for i in 0..<10 {
print("Ⓜ️" , i)
a = i
}
}
print("After Queue \(a)")
它会等到循环结束,但在这种情况下你的邮件线程会阻塞。
你也可以做同样的事情
let myGroup = DispatchGroup()
myGroup.enter()
//// Do your task
myGroup.leave() //// When your task completes
myGroup.notify(queue: DispatchQueue.main) {
////// do your remaining work
}
最后一件事。如果您想在任务使用DispatchQueue完成时使用completionHandler,则可以使用DispatchWorkItem
。
以下是如何使用DispatchWorkItem
let workItem = DispatchWorkItem {
// Do something
}
let queue = DispatchQueue.global()
queue.async {
workItem.perform()
}
workItem.notify(queue: DispatchQueue.main) {
// Here you can notify you Main thread
}
答案 2 :(得分:4)
该解决方案的Swift 5版本
func myCriticalFunction(){ var value1:字符串? var value2:字符串?
let group = DispatchGroup()
group.enter()
//async operation 1
DispatchQueue.global(qos: .default).async {
// Network calls or some other async task
value1 = //out of async task
group.leave()
}
group.enter()
//async operation 2
DispatchQueue.global(qos: .default).async {
// Network calls or some other async task
value2 = //out of async task
group.leave()
}
group.wait()
print("Value1 \(value1) , Value2 \(value2)")
}
答案 3 :(得分:1)
使用调度组
dispatchGroup.enter()
FirstOperation(completion: { _ in
dispatchGroup.leave()
})
dispatchGroup.enter()
SecondOperation(completion: { _ in
dispatchGroup.leave()
})
dispatchGroup.wait() //Waits here on this thread until the two operations complete executing.
答案 4 :(得分:0)
快捷键4
在这些情况下,您可以使用异步功能。当您使用inputDf.select(inputDf.columns.map(c=> when(col(c) === “\\N”,””).otherwise(col(c)).alias(c)):_*).show
时,有时可能会死锁。
DispatchGroup()