4

我有一个在美国托管的实时 WCF 服务。我想从可以在全世界任何地方使用的 Windows 窗体应用程序访问它。目前我正在印度对其进行测试并尝试访问我在美国托管的网络服务。此应用程序可以在任何连接速度和与服务器的任何距离下使用。因此,服务器的响应速度可能会有所不同。我决定当用户执行某些功能时,我的应用程序将首先更新 UI,然后它将在后台执行服务器更新任务。这将防止应用程序冻结或挂起。以下是其中一种情况。但问题是即使我使用异步函数和线程来更新 UI 和服务器,应用程序仍然冻结。

实际上,我有一个按钮可以在喜欢和不喜欢之间进行切换。当用户单击它时,它应该变为不同,然后它运行一个线程在后台更新服务器。以下是 Button 的点击事件的代码:

async private void btnLike_Click(object sender, EventArgs e)
{
      new System.Threading.Thread(new System.Threading.ThreadStart(changeLike)).Start();
      await LikeContent();
}

changeLike功能:

private void changeLike()
{
     if(btnLike.Text.Equals("Like"))
             btnLike.Text="Unlike";
     else
             btnLike.Text="Like";
}

LikeContent功能:

async Task<int> LikeContent()
{
      await Global.getServiceClient().addContentLikeAsync(cid, uid);

      System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(reloadLikes));
      t.Start();
      return 0;
}

addContentLikeAsync()函数是一个 WCF Web 服务函数,用于更新服务器上的用户喜欢。 reloadLikes()用户喜欢内容后,从服务器更新喜欢的数量。

请告诉我如何修改我的代码,以便应用程序立即更新 LIKE 按钮而不是冻结一段时间然后更新 LIKE 按钮?因为这个“有时”会给网速较低的用户留下不好的印象。

4

1 回答 1

3

首先,我假设该btnLike_Click方法是在 UI 线程上调用的。在这种情况下,不要调用changeLike()单独的线程。

async private void btnLike_Click(object sender, EventArgs e)
{
      changeLike();
      await LikeContent();
}

二、一定要编组回UI线程之前reloadLikes()

async Task<int> LikeContent()
{
      await Global.getServiceClient().addContentLikeAsync(cid, uid);

      // Ensures this occurs on the UI thread - WinForms
      Invoke((Action)reloadLikes);

      return 0;
}
于 2013-08-30T09:05:37.123 回答