[swift-evolution] [Concurrency] async/await + actors: cancellation

Jan Tuitman jan.tuitman at gmail.com
Fri Aug 18 01:53:23 CDT 2017


Hi,


After reading Chris Lattners proposal for async/await I wonder if the proposal has any way to cancel outstanding tasks.

I saw these two:

@IBAction func buttonDidClick(sender:AnyObject) {
  // 1
  beginAsync {
    // 2
    let image = await processImage()
    imageView.image = image
  }
  // 3
} 


And:

/// Shut down the current coroutine and give its memory back to the
/// shareholders.
func abandon() async -> Never {
  await suspendAsync { _ = $0 }
}


Now, if I understand this correctly, the second thing is abandoning the task from the context of the task by basically preventing the implicit callback of abandon() to ever be called.

But I don't see any way how the beginAsync {} block can be canceled after a certain amount of time by the synchronous thread/context that is running at location //3

shouldn't beginAsync return something which can be checked if the block passed in to it is finished/ waiting/ ...? and which has a method to cancel it?
I know Thread.cancel (which existed in some programming languages) is evil because you never know where it stops, but it seems strange to me, that there is no way to communicate with the running process in //2.

Then there is this example:

func processImageData() async throws -> Image {
  startProgressBar()
  defer {
    // This will be called when error is thrown, when all operations
    // complete and a result is returned, or when the coroutine is
    // abandoned. We don't want to leave the progress bar animating if
    // work has stopped.
    stopProgressBar()
  }

let dataResource  = try await loadWebResource("dataprofile.txt")
  let imageResource = try await loadWebResource("imagedata.dat")
  do {
    let imageTmp    = try await decodeImage(dataResource, imageResource)
  } catch _ as CorruptedImage {
    // Give up hope now.
    await abandon()
  }
  return try await dewarpAndCleanupImage(imageTmp)
}


this seems to wrap other asynchronous functions in a new async function so it can add the defer logic and abandon logic, but this seems to me only adding more checking of the spawned process and thus not sufficient enough to deal with an external reason in location //3 (for example the process running //3 receives an event that the app is about to be quitted). 

so I am a bit confused here, am I missing something? How would //2 be canceled from location //3, or how would //3 trigger an abandoment inside //2 ?

Jan Tuitman



More information about the swift-evolution mailing list