Как запускать задачи только в одном потоке? - PullRequest
0 голосов
/ 10 июля 2019

Скажем, у меня есть несколько замыканий записи в базу данных, и я хочу выполнить их в одном потоке, но не в виде пакета - мне нужно обновлять интерфейс после каждой записи.

Последовательные очереди, такие как:

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

или

DispatchQueue(label: "hello world").async {}

работают в любом потоке, который они хотят запустить, хотя бы последовательно.

Как я могу иметь очередь, которая выполняется только в одном фоновом потоке?

1 Ответ

2 голосов
/ 11 июля 2019

Как уже отмечали другие, на каком потоке работает код, это не имеет значения. Подобные проблемы с производительностью, как правило, зависят от простого последовательного выполнения задач по одному, чтобы они не перекрывались и не сталкивались с ресурсами.

Самое простое решение - создать последовательную очередь. (напечатано в Safari, поэтому стоит каждого копейки, за которое вы заплатили)

let queue = DispatchQueue(label: "db.update", qos: .utility, attributes: [], autoreleaseFrequency: .inherit, target: nil)

var progress: Int = 0

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

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

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

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

Ключ заключается в том, что каждый блок выполняется последовательно (поскольку очередь не является «параллельной»), и следующий блок не начнется, пока не закончится предыдущий. Каждый блок может выполняться или не выполняться в одном и том же потоке, но это не должно иметь значения.

Результаты / прогресс одного блока можно легко передать следующему блоку с помощью переменных закрытия.

...