2

我已经将一个应用程序从 Android 移植到 Windows Phone 7,并且能够使用同步调用文件 io 等没有很多问题(我使用线程,所以这简化了事情)。

但是,现在我正在移植到 Windows 8 商店应用程序,并且 XxxAsync() 方法在 api 中很猖獗。

我是否应该盲目地使用异步 api 并希望获得最好的结果?

我有各种疑问......例如:

假设用户点击 Save 按钮来保存数据模型。所有的保存都是异步完成的。这意味着用户可以在保存数据模型时继续更改数据模型。如果在中途修改,这不会弄乱数据并损坏他的文件吗?

这如何使开发人员更容易?

我已经阅读了各种异步文章(例如this),但我觉得好像我可能遗漏了一些东西......

感谢您的洞察力。

4

6 回答 6

1

在 UI 中使用异步的想法是所有代码都一个线程(UI 线程)上运行。当用户单击 Save 按钮时,您的处理程序将运行。此时,UI 正忙于运行您的代码,因此 UI 不是交互式的。当您准备好要发送到服务器的数据快照后,您将启动异步保存,并且(从技术上讲)您的处理程序已完成。控制权传递回 UI,它再次变得响应。

此时,用户可以更新数据模型,但操作系统并未查看数据模型。它只是确保将单独的数据缓冲区(您在保存按钮处理程序中创建的快照)发送到服务器。发生这种情况后,您的异步回调将再次执行,在 UI 线程上。根据您使用的版本,您可能需要使用BeginInvoke手动将该调用转移到 UI 线程。

这与浏览器内的 JavaScript 中使用的模型完全相同。

它并不能完全解决所有同步问题。例如,除非您在上传期间禁用“保存”按钮,否则用户可以在服务器已经接收到第一次保存时再次单击“保存”。但这只是服务器需要担心的一个问题,它更好地能够应对两个同时尝试的保存。

您可能遇到的一个可能问题是您以前版本的应用程序。如果你到处都在使用线程,你是否正确地使用了锁或线程安全的数据结构?您描述的问题肯定存在于自由线程应用程序中!

于 2012-11-21T09:31:40.427 回答
1

您应该了解为什么以及何时使用异步方法,切勿盲目使用它们。当然,这几乎适用于任何编程技术,但在异步情况下尤其重要,因为如果您不知道发生了什么,将来很容易搞砸事情。

重要的是要了解您提到的异步问题与 async/await 和使用手动线程解决方案没有什么不同。如果您不使用 async/await(或手动构建的线程),您的 UI 可能会感觉迟缓或受到恼人的锁定。如果您确实使用它,您必须通过禁用输入控件、缓存正在保存的数据或您拥有的东西来补偿您的 UI不会锁定的事实。

散布在现代 API 中的异步方法通常不会改变您对异步或多线程代码的看法,只是将这些想法应用于实际代码是多么容易。

于 2012-11-21T09:16:49.240 回答
1

我是否应该盲目地使用异步 api 并希望获得最好的结果?

在 Windows Phone 平台上,您确实必须使用asyncAPI,但我建议您不要“盲目地”使用它们。首先了解它们;我的博客上有一个async介绍,可能会有所帮助。

假设用户点击 Save 按钮来保存数据模型。所有的保存都是异步完成的。这意味着用户可以在保存数据模型时继续更改数据模型。如果在中途修改,这不会弄乱数据并损坏他的文件吗?

是的。一种常见的做法是在请求未完成时复制数据和/或禁用控件,例如,此代码将在第一次请求保存时复制数据并禁用保存按钮,直到保存完成:

public async Task SaveAsync(MyData data) { ... }

// Logically, this is an asynchronous ICommand.Execute implementation.
public async void SaveCommand()
{
  saveInProgress = true;
  dirty = false;
  MyData data = CopyData();
  await SaveAsync(data);
  saveInProgress = false;
}

// Logically, this is an ICommand.CanExecute implementation.
public bool CanSave { get { return !saveInProgress && dirty; } }
private bool saveInProgress, dirty;

使用线程保存时,您面临完全相同的问题。

这如何使开发人员更容易?

async代码比使用线程的代码更易于维护。

于 2012-11-21T13:14:30.720 回答
1

你是对的,你必须保护你的数据,但这与使用单独的线程没有什么不同。异步模式让您无需显式使用线程即可创建响应式应用程序,但它不能解决访问共享资源的问题。我喜欢来自 channel9 视频之一的引述:响应能力带来责任。

于 2012-11-21T09:19:38.497 回答
1

请记住,仅仅因为代码异步执行,并不意味着您必须允许用户在保存数据时继续更改数据。恕我直言,它确实可以提供更好的用户体验,因为您可以决定阻止用户进一步更改数据的方法。

如果您同步保存并且需要很长时间(例如 30 秒),则用户将面临 30 秒的冻结、无响应屏幕。许多用户会认为应用程序已经崩溃。然而,虽然这是一个异步模型,但您可以简单地显示一条消息(和状态栏)告诉用户发生了什么。此外,您可以选择允许他们访问应用程序的其他功能。

于 2013-05-29T12:02:03.860 回答
0

我是否应该盲目地使用异步 api 并希望获得最好的结果?

不是,肯定不是。异步内容非常好,可以为用户带来灵活的用户体验,但正如您所言,在异步内容执行时会带来程序功能资产管理的复杂性。

对于移动设备(不仅是),基本思想是向用户提供一些progress信息,和/或disablehideUI 控件(功能访问点)使用这些信息,在特定时刻可能会以某种方式伤害用户。

于 2012-11-21T09:18:53.627 回答