2015-11-09 2 views
1

Я адаптировал следующий код, чтобы попытаться загрузить из веб-api код asp.net от Wasson.Как я могу проверить, чтобы этот код действительно работал async?

static public async Task<IEnumerable<T>> ExecuteAsync(HttpClient client, String endPoint) 
    { 
     IEnumerable<T> result = null; 
     HttpResponseMessage response = client.GetAsync(endPoint).Result; 
     response.EnsureSuccessStatusCode(); 
     if (response.IsSuccessStatusCode) 
     { 
      var tResult = await response.Content.ReadAsStringAsync(); 
      result = JsonConvert.DeserializeObject<IEnumerable<T>>(tResult); 
     } 
     return result; 
    } 

Как я уже оформил, я думаю, что эта процедура будет работать асинхронно, но я не знаю, как проверить, чтобы убедиться, что он делает.

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

Вызывающая процедура выглядит следующим образом:

public virtual IEnumerable<T> Fill() 
    { 
     IEnumerable<T> result = null; 
     try 
     { 
      using (var client = CreateClient("", new MediaTypeWithQualityHeaderValue("application/json"))) 
      { 

       String _endPoint = "api/" + typeof(T).Name + "/Get"; 

       result = (ExecuteAsync(client, _endPoint)).Result; 
      } 
     } 
     catch (Exception ex) 
     { 
      LogError(ex.Message); 

     } 
     return result; 
    } 

Является ли эта комбинация, вероятно, работать асинхронно, как я хочу, чтобы это?

Причина, по которой я хочу иметь возможность запускать ее асинхронно, заключается в том, что подпрограммы Fill извлекают большие объемы данных из базы данных. Это скорее случай большого количества отдельных записей, чем большой размер для каждой записи, хотя размер некоторых записей также может быть проблемой.

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

В этом случае не имеет значения, подключаюсь ли я непосредственно к базе данных или через веб-api. Я использую: в некоторых случаях это занимает много времени.

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

Я изначально сформировал код после образца кода Майка Уосона, но обнаружил, что код висит бесконечно, даже если он скомпилирован.

Помогло ли это в ситуации с ситуацией немного лучше?

+0

порядка № '.Result' делает его блокирующий вызов. 'Fill' должен быть помечен как' async', поэтому вы можете вызывать 'result = await ExecuteAsync (client, _endpoint);' –

+0

В Visual Studio я считаю, что ваш вывод будет сообщать вам, когда будут использоваться потоки. Именно так я всегда видел, что async на самом деле создает потоки. Моя логика, вероятно, ошибочна, но если она не показывает несколько потоков там, то я предполагаю, что это не так .... и до сих пор это было правильно. – trueCamelType

+0

Что касается тестирования некоторых предложений. Сначала я попал в ловушку, используя 'await Task.Delay (TimeInMillisecondsHere)', но потом понял, что вам нужна операция блокировки для фактического тестирования, которая теперь используется для циклов типа 'for (int i = 0; i kirotab

ответ

0

Не уверен, что вы после этого здесь. Код, который вы отправили, по-прежнему будет блокировать поток, на котором он включен, поскольку вы вызываете результат, который будет заблокирован.

result = (ExecuteAsync(client, _endPoint)).Result; 

Вы могли бы сделать его асинхронным, позволяя асинхр и ждать ключевых слов распространяется обратно к тому, что метод первоначально создан запрос.

public virtual async Task<IEnumerable<T>> Fill() 
{ 
    ... 
    result = await ExecuteAsync(client, _endPoint); 
    ... 
} 

Однако я не уверен, что это действительно то, что вы после этого, так как вы упоминаете

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

По умолчанию, создание асинхронных операций не решит это для вас. Операция, которая занимает 15 секунд для завершения, займет 15 секунд, независимо от того, является ли она синхронной или асинхронной. Разница в том, что если он асинхронный, вы становитесь более эффективным с точки зрения ресурсов (это означает, что вы освободите поток, чтобы выполнить другие обязанности, ожидая чего-то для завершения).

Однако вы можете использовать задачи для достижения параллелизма.Возьмем, к примеру:

public void DoWork() 
{ 
    Thread.Sleep(10000); 
} 

public void DoMoreWork() 
{ 
    Thread.Sleep(10000); 
} 

Если мы назвали эти два типа этого

DoWork(); 
DoMoreWork(); 

Тогда что бы 20000 мс или 20 секунд И если мы делаем это асинхронный

public async Task DoWork() 
{ 
    await Task.Delay(10000); 
} 

public async Task DoMoreWork() 
{ 
    await Task.Delay(10000); 
} 

и вызов это нравится

await DoWork(); 
await DoMoreWork(); 

Затем он будет длиться 20 секунд. Однако, так как DoWork и DoMoreWork могут работать независимо от eachothers мы могли бы запустить их оба в то же самое время, делая

await Task.WhenAll(DoWork(), DoMoreWork()); 

Это (в идеальном мире) приведет к обеим задачам делаются в течение 10 секунд, вдвое сократить время на пользователь должен ждать.

Надежда Я пролить некоторый свет на вопрос :)

Смежные вопросы