Real-Serious-Games / C-Sharp-Promise

Promises library for C# for management of asynchronous operations.
MIT License
1.19k stars 149 forks source link

Not Usable inside Tasks? #102

Closed User124125 closed 4 years ago

User124125 commented 4 years ago

Hi there, im quite a noob so please correct me.

Is it possible that the promises are not usable inside a task?

I have this function and it wont work inside the task.Run(), but it works outside of task.Run()

private async Task authenticationAsync()
    {

            await Task.Run( () => {
            RestClient.Post<signInResponse_model>(someUri, someString)
            .Then(res =>
            {
                currentIDToken = res.idToken;
                currentUID = res.idToken;
                Debug.Log("idtoken: " + currentIDToken + " | UID: " + currentUID);
            })
            .Catch(error =>
            {
                Debug.Log(error.Message);
            });
           });
           Debug.Log("Outside of task will not run either");
   }

It does not Debug.Log anything at all ...

jdnichollsc commented 4 years ago

@AlexPGithub what version of Unity are you using? and what version of .NET Framework?

RoryDungan commented 4 years ago

There's no reason the promises shouldn't work inside Tasks although if your task is running on another thread I'm not sure how well Unity handles sending messages to the Debug.Log from different threads. Are you able to attach a debugger to the code? My first guess here would be that RestClient.Post is never resolving, which is possible if there is no timeout for the web request.

Arvtesh commented 4 years ago

While technically it is possible to use promises with async/await code, you should never do this. Choose one approach an go with it all the way.

As for your sample, RestClient is based on UnityWebRequest (afaik). If so, it might not work as expected when used in any non-Unity thread (like most Unity APIs). Another problem with it, it assumes the Then is called on the same thread as Post, which is probably not the case.

Here's how your method should look like:

private Task AuthenticateAsync()
{
    var tcs = new TaskCompletionSource<object>();

    RestClient.Post<signInResponse_model>(someUri, someString)
        .Then(res =>
        {
            currentIDToken = res.idToken;
            currentUID = res.idToken;

            tcs.SetResult(null);
        })
        .Catch(error =>
        {
            Debug.LogException(error);
            tcs.SetException(error);
        });

    return tcs.Task;
}