Ожидание асинхронной функции (запрос Http) перед загрузкой формы - PullRequest
0 голосов
/ 26 июня 2018

Я пишу приложение winform и хотел бы отправить запрос Http Post и получить ответ до загрузки основной формы. Пока что у меня следующая ситуация:

Если я сделаю это, загрузка формы отправит запрос, и форма будет загружена немедленно. Ответ на запрос будет получен позже, но в то же время можно нажать любую кнопку в форме (не идеально)

private async void Form1_Load(object sender, EventArgs e)
{
    //client is a HttpClient
    //byteContent is a ByteArrayContent
    using (HttpResponseMessage response = await client.PostAsync("theUrl", 
      byteContent))
    {
        response.EnsureSuccessStatusCode();
        Trace.WriteLine(response.ToString());
    }

}

Итак, я изменил код на это и подумал, что форма загрузится после получения ответа на запрос. Однако вместо этого происходит следующее: форма появляется до получения ответа, но мышь показывает вращающуюся загрузочную форму, поэтому любые кнопки в форме недоступны. После получения ответа кнопки в форме становятся доступными.

Это правильно, но выглядит не очень хорошо.

private async void Form1_Load(object sender, EventArgs e)
{
    //client is a HttpClient
    //byteContent is a ByteArrayContent
    var PostTask = client.PostAsync("theUrl", byteContent);
    PostTask.Wait(); //blocking here

    using (HttpResponseMessage response = PostTask.Result)
    {
        response.EnsureSuccessStatusCode();
       Trace.WriteLine(response.ToString());
    }

}

Как правильно сделать то, что я хочу:

Что форма показывает только после успешного получения ответа?

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Почему вы вызываете Wait() и Result в методе async?Вы видели какие-либо предупреждения компилятора?

Попробуйте это:

private async void Form1_Load(object sender, EventArgs e)
{
    try
    {
        this.Enable = false;

        //client is a HttpClient
        //byteContent is a ByteArrayContent

        using (var response = await client.PostAsync("theUrl", byteContent))
        {
            response.EnsureSuccessStatusCode();
            Trace.WriteLine(response.ToString());
        }
    }
    finally
    {
        this.Enable = true;
    }
}
0 голосов
/ 26 июня 2018

Вы не сказали, используете ли вы WinForms или WPF.

Если WinForms, то одной из возможностей будет введение формы «Загрузка».Было бы просто иметь текст:

"Please wait..." 

или что-то еще.После завершения вызова вы можете принудительно перейти к главной форме.Это дает дополнительное преимущество, позволяя вам справиться с ситуацией, когда ваш вызов не завершается.

Если вы используете WPF, вы можете связать видимость элементов управления с completed или *Флаг 1009 * (и обратный показу индикатора прогресса Loading - please wait...).Вы также должны быть в состоянии справиться с этим внутри View Model;Это означает, что вам не нужно иметь свой код внутри события формы.

Я бы также не стал использовать .Wait() для ожидания вашей задачи.Лучшим способом может быть использование чего-то вроде TaskCompletionSource .

...