2013-11-28 3 views
0

Работала с оптимизацией функции поиска клиентов, чтобы он мог выполнять несколько поисков одновременно, не влияя на время загрузки (по крайней мере, много). Поиск работает таким образом, что мы сначала получаем json для внешней службы, преобразуем его в datacontract и затем сохраняем в нашей базе данных и возвращаем объекты объектов.Задача «еще не вычислена»: асинхронный модуль или обработчик завершен, пока асинхронная операция все еще находится на ожидании.

Раньше у меня было все это одним способом и успешно загружалось несколько запросов асинхронно, но затем я мог бы, если бы я мог отделить вызовы служб, которые получают json из части, которая сохраняет ее в нашей собственной базе данных и возвращает объекты, тогда он должен быть в состоянии пойти намного быстрее, поскольку поисковая служба фактически является реальным поиском.

Так что теперь у меня есть два OperationContracts:

[OperationContract] 
    SwepubHeader DoSwepubSearchAdvanced(string searchQuery, string hiddenSearchWord, Dictionary<string, string> advancedSearchParameters); 

    [OperationContract] 
    List<List<SearchItem>> GetSearchResults(List<SwepubHeader> headers); 

Первые идет на службу поиска под названием swepub и retieves вызова JSon и разбирает его на DataContract г. Второй сохраняют данные в базу данных и возвращает данные как объекты EntityFramework. Пользователь может отправить несколько SwepubHeader-DataContract, а затем получить несколько результатов поиска

В веб-сайте, где я хочу, чтобы сделать асинхронные вызовы мой код выглядит следующим образом:

List<Task<SwepubHeader>> _taskList = new List<Task<SwepubHeader>>(); 

    public SwepubHeader[] DoSearchAdvanced(SwepubSearchServiceClient client, string query, 
     string[] subQuerys, Dictionary<string, string> advancedSearchParameters) 
    { 
     _taskList = new List<Task<SwepubHeader>>(); 
     DoSearchAdvancedAsync(client, query, subQuerys, advancedSearchParameters); 

     return _taskList.Select(task => task.Result).ToArray(); 
    } 
    private async void DoSearchAdvancedAsync(SwepubSearchServiceClient client, string query, IEnumerable<string> subQuerys, Dictionary<string, string> advancedSearchParameters) 
    { 
     foreach (string subQuery in subQuerys) 
     { 
      if (!string.IsNullOrWhiteSpace(subQuery)) 
      { 
       // Starts an async search 
       _taskList.Add(client.DoSwepubSearchAdvancedAsync(query, subQuery, 
        advancedSearchParameters)); 
      } 
     } 
     // Awaits all async searches to finish 
     await Task.WhenAll(_taskList); 
    } 

код не по адресу:

return _taskList.Select(task => task.Result).ToArray(); 

Что мне не хватает? Вся задача. Результат покажет «еще не вычисленный». Может ли это иметь какое-то отношение к тому, что я делаю HttpWebRequests в DoSwepubSearchAdvanced?

ответ

4

Проблема, которую вы видите, связана с использованием вами async void. Как правило, вам следует избегать async void; see my MSDN article for more information.

В вашей конструкции есть еще одна проблема: it's not a good idea to wrap asynchronous methods within synchronous methods. Как только вы начнете работать с проблемами async void, вы все равно получите deadlock issues that I describe on my blog.

Правильное решение заменить DoSearchAdvanced с асинхронным способом:

public Task<SwepubHeader[]> DoSearchAdvancedAsync(
    SwepubSearchServiceClient client, 
    string query, string[] subQuerys, 
    Dictionary<string, string> advancedSearchParameters) 
{ 
    return Task.WhenAll(subQuerys 
     .Where(subQuery => !string.IsNullOrWhiteSpace(subQuery)) 
     .Select(subQuery => client.DoSwepubSearchAdvancedAsync(
      query, subQuery, advancedSearchParameters))); 
} 

А затем изменить свой веб-сайт для вызова await результата.

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

  • Нет связанных вопросов^_^