8

根据 Likness(第 164 页,“使用 C# 和 XAML 构建 Windows 8 应用程序”),“执行异步任务时,您必须请求延期。”

所以,如果我没有把他断章取意,这段代码:

private async Task<System.Collections.Generic.KeyValuePair<string, string>> SelectAContactForASlot()
{
    KeyValuePair<string, string> kvp; 
    var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();
    contactPicker.CommitButtonText = "Select";
    var contact = await contactPicker.PickSingleContactAsync();
    if (contact != null)
    {
        kvp = new KeyValuePair<string, string>(contact.Name, contact.Emails[0].ToString());
        return kvp;
    }
    return kvp = new KeyValuePair<string, string>("No Name found", "No email found");
}

...应该是这样的:

private async Task<System.Collections.Generic.KeyValuePair<string, string>> SelectAContactForASlot()
{
    var deferral = e.SuspendingOperation.GetDeferral();
    KeyValuePair<string, string> kvp; 
    var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();
    contactPicker.CommitButtonText = "Select";
    var contact = await contactPicker.PickSingleContactAsync();
    if (contact != null)
    {
        kvp = new KeyValuePair<string, string>(contact.Name, contact.Emails[0].ToString());
        return kvp;
    }
    return kvp = new KeyValuePair<string, string>("No Name found", "No email found");
    deferral.Complete();
}

正确的?

4

1 回答 1

11

请记住,async方法在遇到 an并且必须(异步)等待时返回。await

当您从必须在返回之前完成await的方法中执行操作时,您需要延迟。async void这种“事件”真的是一个命令。例如,“鼠标移动”只是一个事件——系统并不关心你是否处理这个事件。但是“挂起”是一个命令——系统假设当你从命令返回时,你已经做好了被挂起的准备。在这种情况下,延迟是必要的,以通知系统即使您要返回,但您还没有完成。

同样,如果您的后台任务async实现了Run. 因为当Run返回时,您的后台任务被认为已完成,您需要一种方式来说明您还没有真正完成。

您可以通过方法的存在来判断事件处理程序是否支持这一点GetDeferral。例如,Suspending支持 deferral 因为SuspendingEventArgs有一个SuspendingOperation属性有一个GetDeferral方法。在后台任务场景中(即你有一个async void Run),你可以调用传入GetDeferral的.IBackgroundTaskInstanceRun

你的例子SelectAContactForASlot退货示例Task,因此不需要延期。

于 2012-11-16T18:27:58.270 回答