Swift 如何仅在一个线程上运行任务?

Swift 如何仅在一个线程上运行任务?,swift,concurrency,grand-central-dispatch,dispatch-queue,Swift,Concurrency,Grand Central Dispatch,Dispatch Queue,假设我有几个数据库写闭包,我想在一个线程上执行它们,但不是作为一个批处理—我需要在每次写后更新UI 串行队列,如: DispatchQueue.global(qos: .background).async {} 或 不管他们想运行什么线程,都可以连续运行 我怎么能让队列只在一个后台线程上运行呢?正如其他人所指出的,代码在哪个线程上运行并不重要。像这样的性能问题通常取决于简单地按顺序运行任务,一次一个,这样它们就不会与资源重叠或冲突 最简单的解决方案是创建一个顺序队列。(在Safari中输入,值

假设我有几个数据库写闭包,我想在一个线程上执行它们,但不是作为一个批处理—我需要在每次写后更新UI

串行队列,如:

DispatchQueue.global(qos: .background).async {}

不管他们想运行什么线程,都可以连续运行


我怎么能让队列只在一个后台线程上运行呢?

正如其他人所指出的,代码在哪个线程上运行并不重要。像这样的性能问题通常取决于简单地按顺序运行任务,一次一个,这样它们就不会与资源重叠或冲突

最简单的解决方案是创建一个顺序队列。(在Safari中输入,值得你为此付出每一分钱)

关键是每个块都是按顺序执行的(因为队列不是“并发的”),下一个块在前一个块完成之前不会启动。每个块可以在同一个线程上执行,也可以不在同一个线程上执行,但这并不重要


一个块的结果/进度可以通过闭包变量轻松地传递给下一个块。

只要不是主线程,运行哪个线程有什么关系?用例是什么?使用一个核心数据上下文或一个领域。在上下文上使用perform bock时,我可以在任何CoreData线程上执行任何工作而不会出错。它在自己的队列上执行自己的工作。我认为您试图在1个线程上执行是一个错误。执行什么线程并不重要,但队列才是最重要的。我感谢您的努力,如果您能提供您的方法的代码示例,这将非常有帮助,但当仅在一个线程中使用时,Realm仍具有显著的性能优势。我真的很想知道一种记录这种行为的方法。看起来确实是重复的。但仍然没有答案。假设我有一个返回数字N的请求,在接收时它会生成N个请求,每个请求依次是M个请求,以此类推。我有一个进度指示器,显示了一些总计和已加载的项目。我必须解析数据并将其保存在后台,以保持指示器的响应性。问题不在于数据的一致性-如果写操作是串行执行的,就没有问题,这是关于持久化API的技术方面。如果我有一个NSManagedObjectContext或一个存储记录的异步结果的域,以及另一个在通过网络发送之前读取记录的请求,那么它们最终将位于不同的线程中(很可能)。如果使用核心数据并发调试标志运行模式,则此操作将失败。对于Realm,我不确定您是否会看不到以前的记录。所以我想说的是,当你有一个非平凡的网络请求树时,使用model/storage/context集成它们的结果和参数是非常方便的。否则,在闭包之间传递内容并同步它们的结果是非常繁琐的。我个人最终为每个请求创建了一个单独的NSManagedObjectContext,然后将NSManagedObjects从一个闭包传递到另一个闭包,以便在将来的请求闭包中获取数据。使用闭包变量在块之间共享结果很容易。我将更新示例代码以显示这一点。@Rob,你说得对,这些应该是
async
调用。在Safari中编写代码的危害。。。我将更新代码以反映这一点。
DispatchQueue(label: "hello world").async {}
let queue = DispatchQueue(label: "db.update", qos: .utility, attributes: [], autoreleaseFrequency: .inherit, target: nil)

var progress: Int = 0

queue.async {
    // Dome some work, then update the UI
    progress = 2
    DispatchQueue.main.async(execute: {
        // label.text = "did something"
        // progress.doubleValue = Double(progressCounter)
    })
}

queue.async {
    // Do some more work
    progress += 1
    // This won't execute until the first block has finished
}

queue.async {
    // Even more work
    progress += 1
}

queue.async {
    // And so on...
    progress += 1   // This block might, for example, notify the system that everything has finished
    print("progress is finally \(progress)")
}