【问题标题】:Async method failing when called调用时异步方法失败
【发布时间】:2013-04-11 23:46:35
【问题描述】:

我有这个方法

public class WebSearcher : IWebSearcher
{
    private static readonly string _rootUri;
    private static readonly BingSearchContainer _bingContainer;
    private static readonly string _accountKey;

    static WebSearcher()
    {
        _rootUri = ConfigurationSettings.Settings.RootUri;
        _bingContainer = new BingSearchContainer(new Uri(_rootUri));
        _accountKey = ConfigurationSettings.Settings.AccountKey;
        _bingContainer.Credentials = new NetworkCredential(_accountKey, _accountKey);
    }

    public 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 Task.Factory.FromAsync(webQuery.BeginExecute(null, null),
            asyncResult => webQuery.EndExecute(asyncResult));
    }
}

我这样称呼它

public class Client
{
    public static void Main()
    {
        Search();
    }

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

        await Task.WhenAll(tasks);

        for (var i = 0; i < 100; i++)
        {
            Console.WriteLine(tasks[i].Result.First().Title);
        }
    }
}

代码在 WhenAll 行停止执行。

【问题讨论】:

  • 这是什么程序?控制台应用程序?您如何等待包含循环的方法完成?换句话说:如果您询问整个程序的行为,您需要向我们展示您的程序。
  • 包含循环的方法被标记为异步,它是一个控制台应用程序
  • 信息还不够。你能包括你的实际代码吗?这包括您的 Main() 方法、调用 SearchAsynch() 的方法以及介于两者之间的任何方法。
  • @svick 这是所有代码。

标签: c# async-await c#-5.0


【解决方案1】:

您需要将 Search 从 async void 更改为 async Task,然后在 Main 中 Wait() 结果 - 否则,它会在任务启动后退出,但没有任何东西在等待它完成。

【讨论】:

  • 我已经按上述方式更改了我的客户,但结果按顺序出现,这表明它仍然不是异步的。
  • “异步”并不意味着“并行”。如果您在创建每个任务时await,它将按顺序执行。如果您希望同时运行多个SearchAsync 调用,请多次调用它,然后使用Task.WhenAll 将所有任务一起调用await
  • @StephenCleary 我希望我被这一切弄糊涂了。我更习惯于顺序的、可预测的编程。如果我看到一些代码来证明这一点会有所帮助。
  • @SachinKainth:您更新的代码仍然一次一个地阻塞(Result)每个任务,因此是同步的(您仍然没有使用WhenAll)。我在my async intro blog post 上有一个WhenAll 的例子。
  • Main: Search().Wait();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多