Как я могу проверить, если загрузка веб-клиента завершена, прежде чем я выполнить функцию?


Я пытаюсь получить файлы JSON с разных URL-адресов. Как я могу убедиться, что оба файла загружены полностью, прежде чем я попытаюсь выполнить что-то еще.

Мой код выглядит примерно так:

WebClient Url1 = new WebClient();
Url1.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Url1_DownloadStringCompleted);
Url1.DownloadStringAsync(new Uri("http://example.com"));
WebClient Url2 = new WebClient();
Url2.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Url2_DownloadStringCompleted);
Url2.DownloadStringAsync(new Uri("http://anotherexample.com"));

DoSomethingWithJson();

void Url1_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error != null) 
        return;
    json1 = JObject.Parse(e.Result);
}

void Url2_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error != null) 
        return;
    json2 = JObject.Parse(e.Result);
}

Прямо сейчас происходит то, что json1 и json2 возвращают нулевые значения всякий раз, когда я пытаюсь отобразить их в MessageBox внутри DoSomethingWithJson (), и я предполагаю, что это может быть потому, что они не были загружены полностью.

1 2

1 ответ:

Метод DownloadStringAsync() возвращается до загрузки строки, поскольку это асинхронный метод. Если вы переместите метод DoSomethingWithJson() в завершенные обработчики, то он будет вызван после завершения запроса. Вы можете добавить логику в метод DoSomethingWithJson(), чтобы он работал только в том случае, если все переменные, которые ему нужны, заполнены (если вам действительно нужно, чтобы все они были заполнены, прежде чем вы начнете делать что-либо еще).

WebClient Url1 = new WebClient();
Url1.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Url1_DownloadStringCompleted);
Url1.DownloadStringAsync(new Uri("http://example.com"));
WebClient Url2 = new WebClient();
Url2.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Url2_DownloadStringCompleted);
Url2.DownloadStringAsync(new Uri("http://anotherexample.com"));
var json1Done = false;
var json2Done = false;


void Url1_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error != null) 
        return;
    json1 = JObject.Parse(e.Result);
    json1Done = true;
    if(json1Done && json2Done)
    {
        DoSomethingWithJson();
    }
}

void Url2_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error != null) 
        return;
    json2 = JObject.Parse(e.Result);
    json2Done = true;
    if(json1Done && json2Done)
    {
        DoSomethingWithJson();
    }
}

В качестве альтернативы, если вы используете .Net 4.5, то вы можете использовать новые функции async / await:

WebClient Url1 = new WebClient();
var json1Task = Url1.DownloadStringTaskAsync(new Uri("http://example.com"));
WebClient Url2 = new WebClient();
var json2Task = Url2.DownloadStringTaskAsync(new Uri("http://anotherexample.com"));

json1 = await json1Task;
json2 = await json2Task;

DoSomethingWithJson();