1

I'm getting a deadlock on some C# code even though I'm using ConfigureAwait(false). Unfortunately I'm not able to use async all-the-way up so I'm relying on ConfigureAwait.

The situation is that I need to make an HTTP request to retrieve a database access token from Azure AD during the startup of both a web application and a console application. In both cases the program is deadlocking when Autofac attempts to resolve the database token which triggers the web request.The odd thing is that it works twice but fails the third time.

Autofac Module:

 public class AzureActiveDirectoryModule : BaseModule
 {
    protected override bool SupportsMultipleModuleRegistrations => true;

    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<AzureActiveDirectoryService>().As<IAzureActiveDirectoryService>();

        builder.Register(c => c.Resolve<IAzureActiveDirectoryService>().GetAuthenticationContext())
               .As<AuthenticationContext>()
               .SingleInstance();

        builder.Register(c => c.Resolve<IAzureActiveDirectoryService>().GetCertificateCredential())
               .As<ClientAssertionCertificate>()
               .SingleInstance();

        builder.Register(c =>
                         c.Resolve<IAzureActiveDirectoryService>()
                          .GetDatabaseAccessToken(c.Resolve<AuthenticationContext>(), c.Resolve<ClientAssertionCertificate>()))
               .Named<string>(PersistenceModule.DatabaseAccessToken);
    }
}

Service that makes the HTTP Request (I've replaced the http request with a call to google):

public class AzureActiveDirectoryService : IAzureActiveDirectoryService
{

    public string GetDatabaseAccessToken(AuthenticationContext authContext, ClientAssertionCertificate certCred)
    {
        try
        {
            return AcquireDatabaseToken(certCred, authContext).Result;
        }
        catch (Exception ex)
        {
            Log.Error(ex, "Exception occurred while attempting to retrieve database access token.");
        }

        return string.Empty;
    }

    private async Task<string> AcquireDatabaseToken(ClientAssertionCertificate certCred, AuthenticationContext authContext)
    {
            try
            {
                await DoHttpRequestAsync().ConfigureAwait(false);
                return string.Empty;
            }
            catch (Exception ex)
            {
                Log.Error(ex,
                          "An error occurred",
                          ex.ToString());
            }
    }

    private async Task<string> DoHttpRequestAsync()
    {
        using (HttpClient client = new HttpClient())
        {
            client.DefaultRequestHeaders.Accept.Clear();
            HttpRequestMessage requestMessage = new HttpRequestMessage();
            requestMessage.RequestUri = new Uri("http://www.google.com");
            requestMessage.Headers.Accept.Clear();

            client.Timeout = TimeSpan.FromMilliseconds(30000);

            try
            {
                await client.SendAsync(requestMessage).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                var a = ex.Message;
            }

        }

        return string.Empty;
    }
}

Here's the deadlocked thread's (edited) stacktrace (in the console app)-

mscorlib.dll!System.Threading.Monitor.Wait(object obj, int millisecondsTimeout, bool exitContext)   Unknown
mscorlib.dll!System.Threading.Monitor.Wait(object obj, int millisecondsTimeout) Unknown
mscorlib.dll!System.Threading.ManualResetEventSlim.Wait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken)  Unknown
mscorlib.dll!System.Threading.Tasks.Task.SpinThenBlockingWait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken)    Unknown
mscorlib.dll!System.Threading.Tasks.Task.InternalWait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken)    Unknown
mscorlib.dll!System.Threading.Tasks.Task<string>.GetResultCore(bool waitCompletionNotification) Unknown
mscorlib.dll!System.Threading.Tasks.Task<System.__Canon>.Result.get()   Unknown Contoso.Infrastructure.dll!Infrastructure.Azure.AzureActiveDirectoryService.GetDatabaseAccessToken(Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authContext, Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate certCred) Line 101 C#
Contoso.Infrastructure.dll!Infrastructure.Modules.Azure.AzureActiveDirectoryModule.Load.AnonymousMethod__2_2(Autofac.IComponentContext c) Line 30   C#
Autofac.dll!Autofac.RegistrationExtensions.Register.AnonymousMethod__f(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Builder.RegistrationBuilder.ForDelegate.AnonymousMethod__0(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Activate(System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute() Unknown
Autofac.dll!Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(Autofac.Core.ISharingLifetimeScope currentOperationScope, Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)  Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.ResolveComponent(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.TryResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters, out object instance) Unknown
Autofac.dll!Autofac.ResolutionExtensions.ResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.ResolveNamed<string>(Autofac.IComponentContext context, string serviceName, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.ResolveNamed<string>(Autofac.IComponentContext context, string serviceName)    Unknown
Contoso.Infrastructure.dll!Infrastructure.Modules.PersistenceModule.Load.AnonymousMethod__9_0(Autofac.IComponentContext c) Line 54  C#
Autofac.dll!Autofac.RegistrationExtensions.Register.AnonymousMethod__f(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Builder.RegistrationBuilder.ForDelegate.AnonymousMethod__0(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Activate(System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute() Unknown
Autofac.dll!Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(Autofac.Core.ISharingLifetimeScope currentOperationScope, Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)  Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.ResolveComponent(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.TryResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters, out object instance) Unknown
Autofac.dll!Autofac.ResolutionExtensions.ResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.Resolve<System.Data.Common.DbConnection>(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.Resolve<System.Data.Common.DbConnection>(Autofac.IComponentContext context)    Unknown
Contoso.Infrastructure.dll!Infrastructure.Modules.PersistenceModule.Load.AnonymousMethod__9_1(Autofac.IComponentContext c) Line 62  C#
Autofac.dll!Autofac.RegistrationExtensions.Register.AnonymousMethod__f(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Builder.RegistrationBuilder.ForDelegate.AnonymousMethod__0(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Activate(System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute.AnonymousMethod__0()  Unknown
Autofac.dll!Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(System.Guid id, System.Func<object> creator)    Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute() Unknown
Autofac.dll!Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(Autofac.Core.ISharingLifetimeScope currentOperationScope, Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)  Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.ResolveComponent(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.TryResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters, out object instance) Unknown
Autofac.dll!Autofac.ResolutionExtensions.ResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.Resolve<Infrastructure.Persistence.IDbContext>(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.ResolutionExtensions.Resolve<Infrastructure.Persistence.IDbContext>(Autofac.IComponentContext context)  Unknown
Contoso.Infrastructure.dll!Infrastructure.Modules.PersistenceModule.Load.AnonymousMethod__9_2(Autofac.IComponentContext c) Line 68  C#
Autofac.dll!Autofac.RegistrationExtensions.Register.AnonymousMethod__f(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Builder.RegistrationBuilder.ForDelegate.AnonymousMethod__0(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Activate(System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute.AnonymousMethod__0()  Unknown
Autofac.dll!Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(System.Guid id, System.Func<object> creator)    Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute() Unknown
Autofac.dll!Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(Autofac.Core.ISharingLifetimeScope currentOperationScope, Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)  Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.ResolveComponent(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.Core.Activators.Reflection.AutowiringParameter.CanSupplyValue.AnonymousMethod__0()  Unknown
Autofac.dll!Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()    Unknown
Autofac.dll!Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Activate(System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute.AnonymousMethod__0()  Unknown
Autofac.dll!Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(System.Guid id, System.Func<object> creator)    Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute() Unknown
Autofac.dll!Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(Autofac.Core.ISharingLifetimeScope currentOperationScope, Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)  Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.ResolveComponent(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.Features.Collections.CollectionRegistrationSource.RegistrationsFor.AnonymousMethod__1(Autofac.Core.IComponentRegistration cr)   Unknown
System.Core.dll!System.Linq.Enumerable.WhereSelectArrayIterator<System.__Canon, System.__Canon>.MoveNext()  Unknown
System.Core.dll!System.Linq.Buffer<object>.Buffer(System.Collections.Generic.IEnumerable<object> source)    Unknown
System.Core.dll!System.Linq.Enumerable.ToArray<object>(System.Collections.Generic.IEnumerable<object> source)   Unknown
Autofac.dll!Autofac.Features.Collections.CollectionRegistrationSource.RegistrationsFor.AnonymousMethod__0(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)    Unknown
Autofac.dll!Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Activate(System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute() Unknown
Autofac.dll!Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(Autofac.Core.ISharingLifetimeScope currentOperationScope, Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)  Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.ResolveComponent(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.TryResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters, out object instance) Unknown
Autofac.dll!Autofac.ResolutionExtensions.ResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.Resolve<System.Collections.Generic.IEnumerable<Dispatching.Core.Tasks.Core.ITasksConfigurationSet>>(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)  Unknown
Autofac.dll!Autofac.ResolutionExtensions.Resolve<System.Collections.Generic.IEnumerable<Dispatching.Core.Tasks.Core.ITasksConfigurationSet>>(Autofac.IComponentContext context) Unknown
Contoso.Dispatching.Core.dll!Dispatching.Core.Modules.TaskRunnersModule.Load.AnonymousMethod__2_0(Autofac.IComponentContext c) Line 39  C#
Autofac.dll!Autofac.RegistrationExtensions.Register.AnonymousMethod__f(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Builder.RegistrationBuilder.ForDelegate.AnonymousMethod__0(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Activate(System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute.AnonymousMethod__0()  Unknown
Autofac.dll!Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(System.Guid id, System.Func<object> creator)    Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute() Unknown
Autofac.dll!Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(Autofac.Core.ISharingLifetimeScope currentOperationScope, Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)  Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.ResolveComponent(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.Core.Activators.Reflection.AutowiringParameter.CanSupplyValue.AnonymousMethod__0()  Unknown
Autofac.dll!Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()    Unknown
Autofac.dll!Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Activate(System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute.AnonymousMethod__0()  Unknown
Autofac.dll!Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(System.Guid id, System.Func<object> creator)    Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute() Unknown
Autofac.dll!Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(Autofac.Core.ISharingLifetimeScope currentOperationScope, Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)  Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.ResolveComponent(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.TryResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters, out object instance) Unknown
Autofac.dll!Autofac.ResolutionExtensions.ResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.Resolve<Dispatching.Core.Tasks.Core.ITaskManager>(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)    Unknown
Autofac.dll!Autofac.ResolutionExtensions.Resolve<Dispatching.Core.Tasks.Core.ITaskManager>(Autofac.IComponentContext context)   Unknown
Contoso.Dispatching.Core.dll!Dispatching.Core.Modules.DispatchingModule.Load.AnonymousMethod__2_2(Autofac.IComponentContext c) Line 73  C#
Autofac.dll!Autofac.RegistrationExtensions.Register.AnonymousMethod__f(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Builder.RegistrationBuilder.ForDelegate.AnonymousMethod__0(Autofac.IComponentContext c, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> p)   Unknown
Autofac.dll!Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Activate(System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Resolving.InstanceLookup.Execute() Unknown
Autofac.dll!Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(Autofac.Core.ISharingLifetimeScope currentOperationScope, Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)  Unknown
Autofac.dll!Autofac.Core.Resolving.ResolveOperation.Execute(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)    Unknown
Autofac.dll!Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)   Unknown
Autofac.dll!Autofac.Core.Container.ResolveComponent(Autofac.Core.IComponentRegistration registration, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)    Unknown
Autofac.dll!Autofac.ResolutionExtensions.TryResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters, out object instance) Unknown
Autofac.dll!Autofac.ResolutionExtensions.ResolveService(Autofac.IComponentContext context, Autofac.Core.Service service, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters) Unknown
Autofac.dll!Autofac.ResolutionExtensions.Resolve<Dispatching.Core.Worker.DispatcherWorker>(Autofac.IComponentContext context, System.Collections.Generic.IEnumerable<Autofac.Core.Parameter> parameters)    Unknown
Autofac.dll!Autofac.ResolutionExtensions.Resolve<Dispatching.Core.Worker.DispatcherWorker>(Autofac.IComponentContext context)   Unknown
Topshelf.Autofac.dll!Topshelf.Autofac.ServiceConfiguratorExtensions.ConstructUsingAutofacContainer.AnonymousMethod__0_0(Topshelf.Runtime.HostSettings serviceFactory)   Unknown
Topshelf.dll!Topshelf.Builders.DelegateServiceBuilder<Dispatching.Core.Worker.DispatcherWorker>.Build(Topshelf.Runtime.HostSettings settings)   Unknown
Topshelf.dll!Topshelf.Builders.RunBuilder.Build(Topshelf.Builders.ServiceBuilder serviceBuilder)    Unknown
Topshelf.dll!Topshelf.HostConfigurators.HostConfiguratorImpl.CreateHost()   Unknown
Topshelf.dll!Topshelf.HostFactory.New(System.Action<Topshelf.HostConfigurators.HostConfigurator> configureCallback) Unknown
Contoso.Dispatcher.Shell.exe!Dispatcher.Shell.Program.Main() Line 48    C#
[Native to Managed Transition]  
[Managed to Native Transition]  
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) Unknown
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()   Unknown
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state)    Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()    Unknown

EDIT: Perhaps it's not a deadlock - it seems like it's freezing all threads. Here are the top of the stacks of the other threads -

mscorlib.dll!System.Threading.LazyInitializer.EnsureInitializedCore<System.__Canon>(ref System.__Canon target, ref bool initialized, ref object syncLock, System.Func<System.__Canon> valueFactory) Unknown
mscorlib.dll!System.Threading.LazyInitializer.EnsureInitialized<Infrastructure.Persistence.Migrator.FluentMigratorSchemaVersion.MigrationsInfo>(ref Infrastructure.Persistence.Migrator.FluentMigratorSchemaVersion.MigrationsInfo target, ref bool initialized, ref object syncLock, System.Func<Infrastructure.Persistence.Migrator.FluentMigratorSchemaVersion.MigrationsInfo> valueFactory) Unknown
Contoso.Infrastructure.dll!Infrastructure.Persistence.Migrator.FluentMigratorSchemaVersion.EnsureInitialized() Line 43  C#


mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext)  Unknown
mscorlib.dll!System.Threading.WaitHandle.WaitOne(System.TimeSpan timeout, bool exitContext) Unknown
mscorlib.dll!System.Threading.WaitHandle.WaitOne(System.TimeSpan timeout)   Unknown
Microsoft.ApplicationInsights.dll!Microsoft.ApplicationInsights.Channel.InMemoryTransmitter.Runner()    Unknown


mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext)  Unknown
mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext) Unknown
mscorlib.dll!System.Threading.WaitHandle.WaitOne()  Unknown
Microsoft.ServiceBus.dll!Microsoft.ServiceBus.Common.AsyncResult.End<Microsoft.ServiceBus.Messaging.ServiceBusResourceOperations.GetAsyncResult<Microsoft.ServiceBus.Messaging.TopicDescription>>(System.IAsyncResult result)   Unknown
Microsoft.ServiceBus.dll!Microsoft.ServiceBus.Common.AsyncResult<Microsoft.ServiceBus.Messaging.ServiceBusResourceOperations.GetAsyncResult<Microsoft.ServiceBus.Messaging.TopicDescription>>.End(System.IAsyncResult asyncResult)  Unknown
Microsoft.ServiceBus.dll!Microsoft.ServiceBus.Messaging.ServiceBusResourceOperations.EndGet<Microsoft.ServiceBus.Messaging.TopicDescription>(System.IAsyncResult asyncResult)   Unknown
Microsoft.ServiceBus.dll!Microsoft.ServiceBus.NamespaceManager.EndTopicExists(System.IAsyncResult result)   Unknown
Microsoft.ServiceBus.dll!Microsoft.ServiceBus.NamespaceManager.TopicExists(string path) Unknown
Contoso.Infrastructure.dll!Infrastructure.Azure.ServiceBus.ServiceBusTopic.Setup() Line 136 C#
Nick
  • 695
  • 8
  • 23
  • 4
    `Unfortunately I'm not able to use async all-the-way up` - are you sure? Most people who say this just haven't tried hard enough. – Stephen Cleary Aug 23 '16 at 02:40
  • If you're deadlocked, there are two stack traces that need to be examined. I don't see why the code you posted would deadlock, but then you didn't post a good [mcve]. So whatever's causing the issue is as far as I can tell in the code you _didn't_ post. Please improve the question. I do agree with Stephen's response that if you really can't make it async all the way, you should just make it synchronous. But I don't see how that actually _answers_ your question (i.e. why the async version deadlocks). – Peter Duniho Aug 23 '16 at 02:54
  • I didn't have any luck slimming it down to a MCV example but I'll keep trying. Thanks for taking a look. – Nick Aug 23 '16 at 03:21
  • You really should redesign your approach to avoid asynchronous calls while resolving during dependencies. Or alternatively find if there is DI container that allows you that (also it may mean all resolutions in the code will have to be async thus making such container less likely to exist) – Alexei Levenkov Aug 23 '16 at 03:44
  • @PeterDuniho you're probably correct that the problem is in the code didn't post. On that note, what should I be looking out for? – Nick Aug 23 '16 at 04:32
  • 1
    _"looking out for"_ is something that people without access to the running process do. People who have access to the process interrupt the process with the debugger and inspect the stack for each thread, until they have found the two threads that are waiting for each other. Once you have that information in hand, you'll understand the deadlock better and can proceed to considering what your possible solutions might be. This does assume you really are dealing with a deadlock situation and not just some really long wait/timeout issue. Again, without a good [mcve] no one here can say for sure. – Peter Duniho Aug 23 '16 at 04:41
  • Is there a good way to check what individual threads are waiting on? – Nick Aug 23 '16 at 05:02

2 Answers2

5

If you can't make it asynchronous all the way, then make it synchronous all the way:

public class AzureActiveDirectoryService : IAzureActiveDirectoryService
{
    public string GetDatabaseAccessToken(AuthenticationContext authContext, ClientAssertionCertificate certCred)
    {
        try
        {
            return AcquireDatabaseToken(certCred, authContext);
        }
        catch (Exception ex)
        {
            Log.Error(ex, "Exception occurred while attempting to retrieve database access token.");
        }

        return string.Empty;
    }

    private string AcquireDatabaseToken(ClientAssertionCertificate certCred, AuthenticationContext authContext)
    {
        try
        {
            DoHttpRequest();
            return string.Empty;
        }
        catch (Exception ex)
        {
            Log.Error(ex,
                      "An error occurred",
                      ex.ToString());
        }
    }

    private string DoHttpRequest()
    {
        using (WebClient client = new WebClient())
        {
            return client.DownloadString("http://www.google.com");
        }
        return string.Empty;
    }
}
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • Unfortunately the thing I replaced with the HttpClient call is the ADAL library which offers no synchronous method for retrieving access tokens. – Nick Aug 23 '16 at 03:02
  • @Stephen Cleary Would you recommend any of the solutions suggested on these links: http://stackoverflow.com/a/11889209/1559611 http://stackoverflow.com/a/5097066/1559611 – Mrinal Kamboj Aug 23 '16 at 19:48
  • @MrinalKamboj: `ContinueWith` won't get you the token in time to return it, and `RunSync` is an absolutely horrible and dangerous approach, opening up some serious problems with reentrancy. – Stephen Cleary Aug 24 '16 at 01:17
  • @Stephen Cleary what's your view for the proposed solution by OP, `ConfigureAwait(false).GetAwaiter().GetResult()`, as it looks https://msdn.microsoft.com/en-us/magazine/mt238404.aspx, you might not prefer it – Mrinal Kamboj Aug 24 '16 at 05:46
  • @MrinalKamboj: It would require `ConfigureAwait(false)` for every `await` in the entire call tree, including within `HttpClient`. – Stephen Cleary Aug 24 '16 at 12:47
1

The fix was to do

return AcquireDatabaseToken(certCred,authContext).ConfigureAwait(false).GetAwaiter().GetResult();

instead of

return AcquireDatabaseToken(certCred,authContext).Result;
Nick
  • 695
  • 8
  • 23
  • 1
    The reason is that `ConfigureAwait` only applies to the `Task` that is used right there. All upstream `Task` instances still restore their synchronization context. That caused the deadlock in your case. – Nitram Aug 23 '16 at 11:55
  • Following link will help you know that why what you are doing is not a good hack - https://msdn.microsoft.com/en-us/magazine/mt238404.aspx Also check solutions for similar issue at following links: http://stackoverflow.com/a/11889209/1559611 http://stackoverflow.com/a/5097066/1559611 – Mrinal Kamboj Aug 23 '16 at 19:46