【问题标题】:Azure Mobile App - UpdateAsync - waiting for activation "Error"Azure 移动应用程序 - UpdateAsync - 等待激活“错误”
【发布时间】:2019-05-01 09:41:39
【问题描述】:

我有两个项目

首先是带有 Xamarin.Forms 的移动应用

其次是Windows窗体应用程序

两者都具有使用 Azure 移动应用程序创建的相同 API。

Windows 形式 当我尝试使用以下代码使用.Net HttpClient 更新数据库中的一行时:

private void BtnUpdateUser_Click(object sender, EventArgs e)
    {
        UserRepository userRepository = new UserRepository();
        var user = userRepository.GetAllUsers().FirstOrDefault(w => w.UserId == 1)

        user.UserName = "UpdateUserName";

        var result = userRepository.UpdateUser(user.Id, user);
    }

在 UserRepository 类中我有一个名为 UpdateUser

的方法
public User UpdateUser(string id, User user)
    {
        var result = Task.Run(async () => await azureServices.UpdateAsync(id, user)).Result;
        return result;
    }

在 AzureServices 类中我有一个名为 UpdateAsync 的方法

public async Task<T> UpdateAsync(string id, T instance)
    {

        var Uri= new Uri(baseAddress + id + zumoAddition); //"http://localhost:55040/tables/User/48D68C86-6EA6-4C25-AA33-223FC9A27959?zumo-api-version=2.0.0
        var content = JsonConvert.SerializeObject(instance);
        await _httpClient.PatchAsync(Uri, new StringContent(content, Encoding.UTF8, "application/json"));

        return instance;
    }

PatchAsync 是一个extension method,用于使用Windows.Web.Http.HttpClient 执行PATCH 请求

public static async Task<HttpResponseMessage> PatchAsync(this HttpClient Client, Uri requestUri, HttpContent contnet)
    {

        var method = new HttpMethod("PATCH");
        var httpRequestMessage = new HttpRequestMessage(method, requestUri)
        {
            Content = contnet
        };

        var httpResponseMessage = new HttpResponseMessage();
        try
        {
            httpResponseMessage = await Client.SendAsync(httpRequestMessage);
        }
        catch (TaskCanceledException e)
        {
            Debug.WriteLine("Error: " + e.ToString());
        }
        return httpResponseMessage;
    }

在这一行httpResponseMessage = await Client.SendAsync(httpRequestMessage); 我得到这个错误:

{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { x-zumo-server-version: net-2.0.0 X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcQW5hc1xEZXNrdG9wXFB1cmNoYXNlT3JkZXJzQmFja2VuZFxQdXJjaGFzZU9yZGVyc0JhY2tlbmRcdGFibGVzXFVzZXJcNTA1NzdBOTMtOEEzRi00OTEwLUJBOEYtM0MwMkMyOUFDMDUx?= Date: Thu, 29 Nov 2018 10:20:59 GMT Server: Microsoft-IIS/10.0 X-Powered-By: ASP.NET Content-Length: 188 Content-Type: application/json; charset=utf-8 }}

在后端我有一个带有 Patch 方法的控制器:

public Task<User> PatchUser(string id, Delta<User> patch)
    {
         return UpdateAsync(id, patch);
    }

当我尝试调试后端时,我得到了这个:

Id = 179, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"

问题是:我怎样才能摆脱这个错误以及它出现的原因。

【问题讨论】:

  • UpdateUser 的调用方式和位置。您正在混合异步调用和阻塞调用,这可能导致死锁。既然您使用的是 HttpClient,那么您应该致力于始终保持代码异步
  • 控制器是什么类型。包括它的定义。
  • 控制器调用的UpdateAsync是什么样的?
  • @Nkosi 感谢您的快速回复,UpdateUser 在单击事件BtnUpdateUser_click 时调用,我已修改我的问题控制器类型为Table Controller

标签: c# azure azure-mobile-services patch bad-request


【解决方案1】:

在客户端(Windows 窗体)上,您正在混合使用异步调用和阻塞调用,例如 .Result,这可能会导致死锁。

既然您使用的是HttpClient,那么您应该致力于始终保持代码异步。

UserRepository 需要更新以允许非阻塞异步调用

public Task<User> UpdateUserAsync(string id, User user) {
    return azureServices.UpdateAsync(id, user);
}

事件处理程序允许异步调用,因此需要重构为

private asyc void BtnUpdateUser_Click(object sender, EventArgs e) {
    UserRepository userRepository = new UserRepository();
    var user = userRepository.GetAllUsers().Where(w => w.UserId == 1).FirstOrDefault();

    user.UserName = "UpdateUserName";

    var result = await  userRepository.UpdateUserAsync(user.Id, user);
}

这应该有助于缓解客户端可能发生的任何死锁。

在后端,TableController 操作需要 Delta&lt;User&gt;,根据从客户端发送的内容,它的格式可能不正确。

客户端发送一个普通的aplication/jsonUser作为内容,它可能无法正确绑定到Delta&lt;User&gt;,它只希望处理对模型所做的更改。

【讨论】:

  • 你是对的,客户端发送一个普通的application/jsonUser作为内容,并没有正确绑定到Delta&lt;User&gt;。所以问题一定是如何将 Delta 序列化为 JSON ?
  • @Anas 我很好奇您为什么要手动发送数据而不是使用旨在与服务交互的the managed client for Azure Mobile Apps
  • 谢谢,我尝试使用UpdateAsync,它旨在与微软的服务进行交互。它工作正常。很快我会发布关于第一个问题的答案
【解决方案2】:

我怎样才能摆脱这个错误以及它出现的原因。

您可以通过在以下单个语句中调用和等待来简化代码。

public async Task<User> PatchUser(string id, Delta<User> patch)
{
    return await UpdateAsync(id, patch);
}

更多信息请参考Asynchronous programming with async and await (C#)

【讨论】:

  • 感谢您的回答,但我仍然遇到同样的错误
  • 您是否尝试过使用以下代码进行调试? var user = UpdateAsync(id, patch).Result; return user;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 2013-01-17
  • 2012-07-25
  • 1970-01-01
  • 2019-12-01
相关资源
最近更新 更多