【问题标题】:Async call to external webservice method not returning expected result对外部 Web 服务方法的异步调用未返回预期结果
【发布时间】:2014-07-02 21:09:51
【问题描述】:

**注意我已经问过这个被标记为重复的问题,但是重复的问题并没有帮助解决我在下面遇到的问题。

C# 中异步编程的新手,我在以下工作中遇到了一些困难。

我正在使用外部 WebService 来获取 CarInfo - 他们提供了 Async 方法,在下面的示例中,这些方法返回传入的 Cars 对象数量的字符串。我在如下界面中对此 WebService 进行了自己的抽象:

Task<string> GetTicketIdAsync(Cars[] cars);

我的接口方法实现如下:

public async Task<string> GetTicketIdAsync(Ccars[] cars)
{
    try
    {
        if (_externalServiceClient == null)
        {
            _externalServiceClient = new ExternalServiceClient("WSHttpBinding_IExternalService");
        }

        string ticketID =
            await _externalServiceClient .GetCarInfosAsync(cars)

        return ticketID;
    }
    catch (Exception ex)
    {
        //TODO log 4 net 
        throw new Exception("Failed" + ex.Message);
    }
    finally
    {
        //WCF - Dispose and close client and then set to null
        CloseClient(_externalServiceClient );
        _externalServiceClient = null;
    }

在另一个类中,我有一个方法如下,它将一些汽车添加到数据库中,然后调用同一类中的私有方法从 web 服务获取票。

public void AddCars(List<Cars> cars)
    {
        var ticketId = UpdateCarWithTicketId(cars);

        string test = "Hello-World";
    }

我的带有 TicketId 方法的 UpdateCars 如下:

private async Task<string> UpdateCarWithTicketId(List<Cars> cars)
{
    //Call my abstraction of external web service method
    string ticketId = await _myService.GetTicketIdAsync(cars);

    foreach (var car in cars)
    {
        cars.TicketId = ticketId;
    }

    //Update DB
    _carRepository.Update(cars);

    return ticketId;
}

有几件事 - 如果我在汽车中的 foreach 循环 var car 上设置断点,它似乎永远不会被击中,因此数据库不会得到更新。然后,如果我在字符串 test = "hello world" 行的 AddCars 方法上设置断点 - 当我期望从调用外部 Web 服务返回的唯一字符串时,ticketId 的值会显示状态 WaitingForActivation。

我尝试将 ConfigureAwait(false) 添加到使用 await 的两个调用中,但仍然得到相同的结果。在配置异步方法以正确运行时我缺少什么吗?

编辑-

当前,当用户点击屏幕上的按钮时,这是从 MVC 控制器调用的 -

    [AcceptVerbs(HttpVerbs.Post)]
    public async Task<ActionResult>Upload(CarImport viewModel)
    {
         //list of cars uploaded by user in Excel sheet - code to extract that removed

            await _CarInfoService.AddCars(cars);
        }
        return RedirectToAction("Home");
    }

但是,我在 Build 上收到错误消息,说不能等待 void - 我的 _CarInfoService 上的 AddCars 方法签名是无效的 - 是否应该将其更改为其他内容?

【问题讨论】:

  • 进一步了解你的调用堆栈,你是在调用Task.Wait 还是Task&lt;T&gt;.Result?
  • @StephenCleary - 不 - 我应该在某个地方打电话给那些
  • 不,你不应该使用它们。
  • @StephenCleary - 只是为了围绕这个添加更多上下文,我的 Method void AddCars 将从 MVC 控制器 ActionResult 中 UI 上的按钮调用(尽管它可能会移动到 Web API 控制器) - 所以最终目标我希望用户可以导航到不同的屏幕等,而从外部 WebService 检索数据并将其持久化到数据库(可能需要 3-4 分钟或更长时间)的所有工作都在后台进行
  • @StephenCleary - 进行了编辑 - 我尝试将以下内容添加到我的控制器方法中,尽管我收到一个构建错误说不能等待无效,这是我的 AddCars 方法的签名?

标签: c# .net asynchronous .net-4.5


【解决方案1】:

UpdateCarWithTicketId 返回 Task&lt;string&gt; 而不是 string。您可以通过执行以下操作获得string:

public async void AddCars(List<Cars> cars)
{
    var ticketId = await UpdateCarWithTicketId(cars);

    string test = "Hello-World";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    相关资源
    最近更新 更多