question

afterthoughtgamesllc avatar image
afterthoughtgamesllc asked

How to get LoginWithCustomIDAsync to complete?

We are experiencing an infinite wait for LoginWithCustomIDAsync.

Everything seems fine but the task never completes so it stays on loginTask.Wait() forever. If I go into my dashboard I can see the new user was created in the back end with my title but I never know if finishes.

Is there anything wrong with the code, or a step I am missing to get this to end properly?

PlayFabSettings.TitleId = "************";
            var request = new LoginWithCustomIDRequest { CustomId = customId, CreateAccount = createAccount };
            var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(request);
            loginTask.Wait();


            if (loginTask.Result.Result != null)
            {
                return loginTask.Result.Result;
            }


            if (loginTask.Result.Error != null)
            {
                throw new Exception(loginTask.Result.Error.GenerateErrorReport());
            }


            throw new Exception("Failed to login user");

Thanks for your help.

apissdks
11 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

afterthoughtgamesllc avatar image afterthoughtgamesllc commented ·

So far I tried three different ways of coding this and same thing happens each time. The task never ends. Is there some sort of other "settings" that need to be setup to get this to work in code or on the website?

I'm wondering if I just need to find another solution using a different provider, kinda frustrating.

0 Likes 0 ·
brendan avatar image brendan afterthoughtgamesllc commented ·

No, the issue is with the specifics of Tasks and their usage. Can you please try the code snippet Paul posted below?

0 Likes 0 ·
afterthoughtgamesllc avatar image afterthoughtgamesllc brendan commented ·

I tried that, same thing, the task never completes

0 Likes 0 ·
Show more comments
morphus@heartforgames.com avatar image morphus@heartforgames.com commented ·

Anyone ever get a solution for that issue?

All other task complete without a problem, but that one get complete...

I try with .complete, .wait, .GetAwaiter().GetResult(), Task.WaitAll(task)

That task just never end. I use PlayFabAllSDK V1.80.200901

0 Likes 0 ·
brendan avatar image brendan morphus@heartforgames.com commented ·

Did you try using Paul's solution immediately below (ContinueWith)? Again, Wait/Result can result in a deadlock.

0 Likes 0 ·
morphus@heartforgames.com avatar image morphus@heartforgames.com brendan commented ·

Yes I did and it change nothing.

Honestly I use a lot of async and it's the first time I encounter one causing such issue.

However after posting I found Question 17961, and that solution is working fine.

Personally, I still think there is something weird with that command, but as long as I have a solution, i'm happy :)

Thank

0 Likes 0 ·
Show more comments
1807605288 avatar image
1807605288 answered

Try this:

bool _running = true;
PlayFabSettings.TitleId = "XXXX"; // Please change this value to your own titleId from PlayFab Game Manager
var request = new LoginWithCustomIDRequest { CustomId = "GettingStartedGuide", CreateAccount = true };
var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(request);
loginTask.ContinueWith((result) => { _running = false; });

while (_running)
{
  Console.WriteLine("Waiting for result...");
}

I've found providing an action to the ContinueWith function is the safest and most reliable way to use tasks.

As Brendan describes, using .Wait(), .Result, and etc can cause deadlocks. This is a C# limitation.

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

pagilmor avatar image pagilmor commented ·

We have improved our answer for this: https://docs.microsoft.com/en-us/gaming/playfab/release-notes/2019#191122
In Nov 2019, we added a new class: SynchronizationContextRemover: https://github.com/PlayFab/CSharpSDK/blob/master/PlayFabSDK/source/PlayFabUtil.cs#L156

This class fixes the deadlock where main-threads couldn't block on PlayFab calls. It should be possible now to just call loginTask.Result directly, from any thread, including main/gui threads. Note: this will stutter/lock-up your program, somewhat by design. If you do this, you're blocking a thread that's not designed to be blocked. We verify this in our own testing as well: https://github.com/PlayFab/CSharpSDK/blob/master/PlayFabSDK/UnittestRunner/UUnitTestRunner.cs#L29

If there is a direct-chain between a gui/main thread and your code, you may also have to break the context between that thread, and your sub-threads, the way we do:
```await new PlayFabUtil.SynchronizationContextRemover();```
All PlayFab calls and async invocations do this now, so I suspect that you may need to utilize this technique in your code, if you're having these issues.

0 Likes 0 ·
brendan avatar image
brendan answered

This is actually a fairly common issue - what's happening is that you're encountering a deadlock, due to a mix of sync/async concepts. Microsoft has a very good article on this topic here: https://msdn.microsoft.com/en-us/magazine/jj991977.aspx.

For your specific case, which SDK are you using?

6 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

afterthoughtgamesllc avatar image afterthoughtgamesllc commented ·

I am using the PlayFabAllSDK, is there any reason besides the obvious, I never get to complete, that would cause the deadlock with playfab? there are no sync calls that I can see.

Any thoughts or ideas?

0 Likes 0 ·
afterthoughtgamesllc avatar image afterthoughtgamesllc commented ·

I am using the PlayFabAllSDK

Is there any reason why the code would get stuck in a deadlock? I swear this code worked before, and it is creating the new accounts or logging in to old ones.

0 Likes 0 ·
brendan avatar image brendan afterthoughtgamesllc commented ·

What I actually mean was, are you using the PlayFab C# SDK or the Unity SDK (or one of the others)? I'm guessing it's the C# SDK.

I can't guarantee you'd hit a deadlock every time, so it's possible you may have seen this work in the past. But a wait on an async task is actually a pretty common cause of deadlocks. Given the logic flow, you could simply switch to a lambda operation, potentially. Would that work for you?

0 Likes 0 ·
afterthoughtgamesllc avatar image afterthoughtgamesllc brendan commented ·

Yes I am using c#

0 Likes 0 ·
Show more comments
afterthoughtgamesllc avatar image
afterthoughtgamesllc answered

Here is the issue. We are using Monogame. The situation only happens when using Monogame 3.6, when we use monogame 3.5 the API calls work fine. Even a console application works fine, the minute you call playfab calls from monogame 3.6 no async call ever comes back. We tested this with 2 devs on two different machines.

Seems that playfab is not compatible with Monogame 3.6

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image brendan commented ·

Sorry, but we do not do any testing with MonoGame, and so it's not a supported development environment. I can verify that the code Paul posted works quite well on vanilla C# implementations, so this sounds like an issue you'll need to take up with the MonoGame team.

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.