1

The following code does not print ..In Background.. and prints ..Executing..

I know I am missing something really basic. I read up other questions with the same, but they all seems like they are running the same code.

Some possible duplicates that did not help here

I have extracted the exact code in question, I don't think anything more is needed to help debug this.

func execute() {
        print("..Executing..")
        DispatchQueue.global(qos: .background).async {
           self.doInBackground()

            DispatchQueue.main.async {
                self.doAfterBackgroundCompletes()
            }
        }
    }

 func doInBackground() {

        print("..In Background..")

EDIT

The below works. But I am wondering shouldn't a http request be in a background thread. Atleast in Android if http request is not in the background thread it causes an issue.

func execute() {
        print("..Executing..")
        self.doInBackground()
        self.doAfterBackgroundCompletes()

//        DispatchQueue.global(qos: .background).async {
//            DispatchQueue.main.async {
//                self.doInBackground()
//                self.doAfterBackgroundCompletes()
//            }
//        }
    }
Community
  • 1
  • 1
Siddharth
  • 9,349
  • 16
  • 86
  • 148

4 Answers4

4

I've seen the same behaviour in Swift 4. While I can't explain the it, changing the QoS from .background to .default did execute and that solved my issue. I know it's not a solution as such but I hope it's a reasonable work-around for you.

Josh Paradroid
  • 1,172
  • 18
  • 45
2

Maybe I am missing something? I just ran the following code:

func execute() {
    print("..Executing..")
    DispatchQueue.global(qos: .background).async {
        self.doInBackground()

        DispatchQueue.main.async {
            self.doAfterBackgroundCompletes()
        }
    }
}

func doInBackground() {
    print("..In Background..")
}

func doAfterBackgroundCompletes() {
    print("..COMPLETED..")
}

And the results are:

..Executing..
..In Background..
..COMPLETED..

From where are you calling the execute function?

Just a coder
  • 15,480
  • 16
  • 85
  • 138
1

Here is working code.

DispatchQueue.global().async(execute: {

    print("global...")

    DispatchQueue.main.sync{
        print("main...")
    }

})
0

I had this problem too and solved it by creating a custom dispatch queue, though I believe it could be mitigated (if not solved outright) by increasing the task priority.

I believe the issue was that the global dispatch queue is used by many things, and the global queue has a limited number of concurrent tasks. By adding tasks into the .background queue your item will only run if there are no .utility or higher priority tasks left.

This becomes a problem when for some reason either a lot higher priority tasks are being queued, or if the ones that are happen to be taking an inordinate amount of time. This can be a problem in any queue, though the global queue is probably much more likely to have this issue since more things will use it.

This is from Apple's docs, under the Creating and Managing Dispatch Queues heading:

The actual number of tasks executed by a concurrent queue at any given moment is variable and can change dynamically as conditions in your application change. Many factors affect the number of tasks executed by the concurrent queues, including the number of available cores, the amount of work being done by other processes, and the number and priority of tasks in other serial dispatch queues.

...

As you might expect, tasks in the high-priority concurrent queue execute before those in the default and low-priority queues. Similarly, tasks in the default queue execute before those in the low-priority queue.

Community
  • 1
  • 1
thecodewarrior
  • 196
  • 3
  • 11