Auth0 Home Blog Docs

Need to call the Auth0.OidcClient.WinForms LoginAsync function from a non-async method

I need to call the Auth0.OidcClient.WinForms LoginAsync function from a non async method.

When I try this using the below code I receive a “System.Runtime.InteropServices.COMException: ‘activating a single-threaded class from MTA is not supported (Exception from HRESULT: 0x8000001D)’” exception. If I set the SetSynchronizationContext to WindowsFormsSynchronizationContext the code just hangs on the LoginAsync method with no MTA error.

Any help tracking down this issue or another technique to accomplish the same thing would be greatly appreciated.

Thanks
Scott

Sample Code, called from WinForm button.

   private void LogonNoAsyncButton_Click(object sender, EventArgs e)
    {

        TaskCompletionSource<LoginResult> tcs = new TaskCompletionSource<LoginResult>();
        Thread thread = new Thread(async delegate ()
      {
          try
          {

              // If I uncomment this then no MTA error, but code just hangs
              //if (SynchronizationContext.Current == null)
              //{
              //    SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
              //}

              var clientOptions = new Auth0ClientOptions
              {
                  Domain = "***********",
                  ClientId = "***********",
                  RedirectUri = "***********",
                  PostLogoutRedirectUri = "***********"
              };

              var client = new Auth0Client(clientOptions);
              
              LoginResult result = await client.LoginAsync();

              tcs.SetResult(result);

              // Can show form, so STA thread is good
              //new Form().ShowDialog();

          }
          catch (Exception exception)
          {
              MessageBox.Show(exception.Message);
              throw;
          }

      });
        thread.SetApartmentState(ApartmentState.STA);
        thread.Name = "Auth0ApartmentSTA";
        thread.Start();
        LoginResult loginResult = tcs.Task.Result;
        thread.Join();
        if (!loginResult.IsError)
            MessageBox.Show(loginResult.AccessToken);
    }

Error:
System.Runtime.InteropServices.COMException: ‘Activating a single-threaded class from MTA is not supported (Exception from HRESULT: 0x8000001D)’

Environment:
Windows 10 – Version 10.0.17134 Build 17134,
System Type: x64-based PC
SDK: Auth0.OidcClient.WinForms version 3.1.2
Target Framework: .NET Framework 4.7.2

Similar issue:

Solved my issue with help from this post on stackoverflow.

Here is the routine to call from a non async method.

     public LoginResult Login()
    {
        var tcs = new TaskCompletionSource<LoginResult>();

        var thread = new Thread(delegate ()
        {
            var dispatcher = Dispatcher.CurrentDispatcher;
            dispatcher.InvokeAsync(async delegate
            {
                var clientOptions = new Auth0ClientOptions
                {
                    Domain = "*****",
                    ClientId = "*****",
                    Scope = "*****l",
                    RedirectUri = "*****",
                    PostLogoutRedirectUri = "*****"
                };

                var client = new Auth0Client(clientOptions);

                var extraParameters = new Dictionary<string, string>
                {
                    {"audience", "*****"}
                };

                var loginResult = await client.LoginAsync(extraParameters);

                tcs.SetResult(loginResult);
                dispatcher.BeginInvokeShutdown(DispatcherPriority.Normal);
            });

            Dispatcher.Run();
        });
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();

        return tcs.Task.Result;
    }

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.