等到任务完成

时间:2017-02-27 11:09:39

标签: swift multithreading asynchronous swift3 grand-central-dispatch

我怎样才能让我的代码等到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中编写。

5 个答案:

答案 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()