[GH-ISSUE #21] Support for async/await callbacks with result. #14

Closed
opened 2026-05-05 10:59:18 -06:00 by gitea-mirror · 2 comments
Owner

Originally created by @pauldotknopf on GitHub (Jul 21, 2018).
Original GitHub issue: https://github.com/qmlnet/qmlnet/issues/21

Consider this C# code.

C#

public async Task<string> AsyncMethod()
{
    await Task.Delay(TimeSpan.FromSeconds(5);
    return "test";
}

Currently, we support invoking this method and having the continuations happen on the UI thread.

Qml

o.AsyncMethod()

The problem is that the caller has no way of knowing when this function is completed.

Originally created by @pauldotknopf on GitHub (Jul 21, 2018). Original GitHub issue: https://github.com/qmlnet/qmlnet/issues/21 Consider this C# code. **C#** ```c# public async Task<string> AsyncMethod() { await Task.Delay(TimeSpan.FromSeconds(5); return "test"; } ``` Currently, we support invoking this method and having the continuations happen on the UI thread. **Qml** ```js o.AsyncMethod() ``` The problem is that the caller has no way of knowing when this function is completed.
Author
Owner

@pauldotknopf commented on GitHub (Jul 21, 2018):

Scenario 1

C#

public async Task AsyncMethod()
{
    await Task.Delay(TimeSpan.FromSeconds(5);
}

Qml

o.AsyncMethod(function() {
    // Called when the async function is finished.
})

Scenario 2

C#

public async Task AsyncMethod(CancellationToken cancelToken)
{
    await Task.Delay(TimeSpan.FromSeconds(5);   
}

Qml

var cancelToken = {
    canceled: false,
    cancel: function() {
        canceled = true
    }
}
o.AsyncMethod(function() {
    // Called when the async function is finished.
}, cancelToken /*optional, used to cancel the task*/)
// You can store "cancelToken" somewhere if you'd like. Use this for a "Cancel" button in your UI.

Scenario 3

C#

public async Task<string> AsyncMethod()
{
    await Task.Delay(TimeSpan.FromSeconds(5);
    return "test";
}

Qml

o.AsyncMethod(function(result) {
    // Called when the async function is finished.
})

Scenario 4

C#

public async Task<string> AsyncMethod(CancellationToken cancelToken)
{
    await Task.Delay(TimeSpan.FromSeconds(5);
    return "test";
}

Qml

var cancelToken = {
    canceled: false,
    cancel: function() {
        canceled = true
    }
}
o.AsyncMethod(function(result) {
    // Called when the async function is finished.
}, cancelToken /*optional, used to cancel the task*/)
// You can store "cancelToken" somewhere if you'd like. Use this for a "Cancel" button in your UI.

Notes

Some things to take away from this is that there will never be any interacting with Task objects as a return type. The async methods will always be transformed in Qml to a method without a return type (void).

If any method returns Task, there will also be a check to see if the last parameter for the method is a CancellationToken. If it is, is will be treated specially by the integration.

<!-- gh-comment-id:406765656 --> @pauldotknopf commented on GitHub (Jul 21, 2018): # Scenario 1 **C#** ```c# public async Task AsyncMethod() { await Task.Delay(TimeSpan.FromSeconds(5); } ``` **Qml** ```js o.AsyncMethod(function() { // Called when the async function is finished. }) ``` # Scenario 2 **C#** ```c# public async Task AsyncMethod(CancellationToken cancelToken) { await Task.Delay(TimeSpan.FromSeconds(5); } ``` **Qml** ```js var cancelToken = { canceled: false, cancel: function() { canceled = true } } o.AsyncMethod(function() { // Called when the async function is finished. }, cancelToken /*optional, used to cancel the task*/) // You can store "cancelToken" somewhere if you'd like. Use this for a "Cancel" button in your UI. ``` # Scenario 3 **C#** ```c# public async Task<string> AsyncMethod() { await Task.Delay(TimeSpan.FromSeconds(5); return "test"; } ``` **Qml** ```js o.AsyncMethod(function(result) { // Called when the async function is finished. }) ``` # Scenario 4 **C#** ```c# public async Task<string> AsyncMethod(CancellationToken cancelToken) { await Task.Delay(TimeSpan.FromSeconds(5); return "test"; } ``` **Qml** ```js var cancelToken = { canceled: false, cancel: function() { canceled = true } } o.AsyncMethod(function(result) { // Called when the async function is finished. }, cancelToken /*optional, used to cancel the task*/) // You can store "cancelToken" somewhere if you'd like. Use this for a "Cancel" button in your UI. ``` # Notes Some things to take away from this is that there will never be any interacting with ```Task``` objects as a return type. The async methods will always be transformed in Qml to a method without a return type (```void```). If any method returns ```Task```, there will also be a check to see if the last parameter for the method is a ```CancellationToken```. If it is, is will be treated specially by the integration.
Author
Owner

@pauldotknopf commented on GitHub (Jul 25, 2018):

I'm thinking something a little differently for this now.

Methods that return Task will stay as is. You can always do this from qml (but don't):

var task = netObject.MethodReturningTask()
task.Wait()

I am going to add this global Net object.

var Net = {
    await: function(task, callback) {
        // PInvoke magic!
    }
}

Then we can do something like this.

var task = netObject.MethodReturningTask()
Net.await(task, function(result) {
    // This is raised in qml, with an optional "result" argument for "Task<T>" types.
})
<!-- gh-comment-id:407603834 --> @pauldotknopf commented on GitHub (Jul 25, 2018): I'm thinking something a little differently for this now. Methods that return ```Task``` will stay as is. You can always do this from qml (but don't): ```js var task = netObject.MethodReturningTask() task.Wait() ``` I am going to add this global ```Net``` object. ```js var Net = { await: function(task, callback) { // PInvoke magic! } } ``` Then we can do something like this. ```js var task = netObject.MethodReturningTask() Net.await(task, function(result) { // This is raised in qml, with an optional "result" argument for "Task<T>" types. }) ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/qmlnet#14
No description provided.