title: Kotlin: Why isn't job.invokeOnCompletion() block running on main thread?
body: <p>In my Android application I have code that should run periodically in its own coroutine and should be cancelable.</p>
  <p>for this I have the following functions:</p>
  <p><strong>startJob()</strong>: Initializes the job, sets up <code>invokeOnCompletion()</code> and starts the work loop in the respective scope</p>
  <pre><code>private fun startJob() {
      if (::myJob.isInitialized &amp;&amp; myJob.isActive) {
          return
      }
      myJob= Job()
      myJob.invokeOnCompletion {
          it?.message.let {
              var msg = it
              if (msg.isNullOrBlank()) {
                  msg = &quot;Job stopped. Reason unknown&quot;
              }
              myJobCompleted(msg)
          }
      }
      CoroutineScope(Dispatchers.IO + myJob).launch {
          workloop()
      }
  }
  </code></pre>
  <p><strong>workloop()</strong>: The main work loop. Do some work in a loop with a set delay in each iteration:</p>
  <pre><code>private suspend fun workloop() {
      while (true) {
          // doing some stuff here
          delay(setDelayInMilliseconds)
      }
  }
  </code></pre>
  <p><strong>myJobCompleted</strong>: do some finalizing. For now simply log a message for testing.</p>
  <pre><code>private fun myJobCompleted(msg: String) {
      try {
          mainActivityReference.logToGUI(msg)
      }
      catch (e:Exception){
          println(&quot;debug: &quot; + e.message)
      }
  }
  </code></pre>
  <p>Running this and calling <code>myJob.Cancel()</code> will throw the following exception in <code>myJobCompleted()</code>:</p>
  <blockquote>
  <p>debug: Only the original thread that created a view hierarchy can touch its views.</p>
  </blockquote>
  <p>I'm curious as to why this code isn't running on the main thread, since <code>startJob()</code> IS called from the main thread?</p>
  <p>Furthermore: is there a option similar to using a <a href="https://docs.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource?view=net-5.0" rel="nofollow noreferrer">CancellationTokenSource</a> in <code>c#</code>, where the job is not immediately cancelled, but a cancellation request can be checked each iteration of the while loop?
  Immediately breaking off the job, regardless of what it is doing (although it will pretty much always be  waiting for the delay on cancellation) doesn't seem like a good idea to me.</p>