C# асинхронный тупик - почему это происходит в этом случае

У меня есть приложение ASP.Net (на самом деле здесь задействован Lightswitch, но я не уверен, что в этом случае это имеет большое значение).

У меня есть следующий код. Он начинается в LogIn.aspx, который вызывает RegisterUser для события OnLoggedIn.

    public static void RegisterUser(string userName)
    {
        using (var connection = new SqlConnection(IzendaSettings.ConnectionString))
        using (var command = connection.CreateCommand())
        {
            connection.Open();
            command.CommandText = @"SELECT CU.DisplayName, CU.ClientId, C.Name FROM ClientUser CU INNER JOIN Client C on C.ClientId = CU.ClientId WHERE CU.UserName = @userName AND Rights = 0";
            command.Parameters.Add("userName", SqlDbType.NVarChar).Value = userName; 
            using (var reader = command.ExecuteReader())
            {
                if (reader.Read())
                {
                    var unused = RegisterUserAsync(userName, reader.GetString(0), reader.GetInt32(1).ToString(), reader.GetString(0));
                }
            }
        }
    }

    internal static async Task RegisterUserAsync(string userName, string fullName, string clientId, string clientName)
    {
        try
        {
            var token = TokenAuthorization.GetSystemAdministratorToken();
            while (Bootstrap.Initalizing)
            {
                Thread.Yield();
            }
            var izenda = await TenantProcess.Initialize(clientId, clientName, token);
            var connection = await izenda.SetUpConnection(IzendaSettings.ConnectionString);
            await izenda.PutUserInRole("User", userName, fullName, "~/BI/tenantRolePermission.json", connection);
        }
        catch (Exception e)
        {
            Logger.Error("Register User", e);
        }
    }

Асинхронный код блокируется. Я пытаюсь просто запустить его в отдельном потоке, я специально не жду этого.

Изменение вызова RegisterUserAsync на это (с соответствующим захватом SQL перед запуском потока):

Task.Run (() => RegisterUserAsync (userName, user.FullName, user.ClientId, user.ClientName));

Решает проблему. Я понимаю, почему вызов Task.Run решает асинхронный вызов, который вы хотите ждать без блокировки, но я не понимаю, почему в этом случае произошел тупик. (Переменная Initializing была false - я зарегистрировал оператор отладки, чтобы убедиться, что он на самом деле никогда не работал с Thread.Yield, но я не понимаю, почему это все равно повлияет на него).

Почему в старом коде произошла тупиковая ситуация?

0 ответов

Другие вопросы по тегам