【问题标题】:Is this code synchronous as I want it to be?这段代码是否像我想要的那样同步?
【发布时间】:2013-04-01 02:23:18
【问题描述】:

我有这个代码

public async Task<IEnumerable<WebResult>> SearchAsynch(string query)
{
  if (query == null)
  {
     throw new ArgumentNullException("query cannot be null");
  }

  DataServiceQuery<WebResult> webQuery =
 _bingContainer.Web(query, null, null, null, null, null, null, null);

  return await Task.Factory.FromAsync
                 (webQuery.BeginExecute(null, null)
                 , asyncResult => webQuery.EndExecute(asyncResult)
                 );
}

我这样称呼它

public static void Main()
{
   Search().Wait();
}

private static async Task Search()
{
  IWebSearcher webSearcher = new WebSearcher();
  for (var i = 0; i < 100; i++)
  {
      IEnumerable<WebResult> task = await webSearcher.SearchAsynch(i.ToString());

      var enumerator = task.GetEnumerator();
      enumerator.MoveNext();
      Console.WriteLine(enumerator.Current.Title);
   }
}

我的问题是这样的。我希望这 100 个对SearchAsynch 的调用中的每一个都完全独立于彼此,以便第 10 个调用可以在第 9 个调用之前返回并打印其结果。目前似乎没有发生这种情况。有什么我做错了吗?

【问题讨论】:

    标签: c# task-parallel-library .net-4.5 async-await c#-5.0


    【解决方案1】:

    在任务完成后进行处理的最简单方法是定义一个单独的方法来进行处理,如下所示:

    public static async Task SearchAndPrintAsync(IWebSearcher webSearcher, string query)
    {
      var result = await webSearcher.SearchAsync(query);
      using (var enumerator = result.GetEnumerator())
      {
        if (enumerator.MoveNext())
          Console.WriteLine(enumerator.Current.Title);
        else
          Console.WriteLine("<none>");
      }
    }
    

    然后您可以像这样进行并发async 操作:

    private static async Task MainAsync()
    {
        IWebSearcher webSearcher = new WebSearcher();
    
        // Start all SearchAndPrint operations concurrently.
        Task[] tasks = Enumerable.Range(0, 100)
            .Select(i => SearchAndPrintAsync(webSearcher, i))
            .ToArray();
    
        // Wait for them all to complete.
        await Task.WhenAll(tasks);
    
        Console.WriteLine("Done");
    }
    
    public static void Main()
    {
        MainAsync().Wait();
    }
    

    【讨论】:

    • SearchAndPrintAsync 方法违反了关注点分离。它将数据访问与演示混合在一起。
    • 我假设 op 只给了我们示例代码,所以 Console.WriteLine 在逻辑上代表“做进一步处理”。
    • 顺便说一句,我认为在这里使用First()(或FirstOrDefault())会比摆弄枚举器更简单。 (但我意识到你只是从问题中复制了它并修复了它。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 2017-07-24
    相关资源
    最近更新 更多