8

Likness(p。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メソッドは、にヒットすると戻りawait、 (非同期で)待機する必要があることに注意してください。

awaitメソッドからの操作async voidが戻る前に完了する必要がある場合は、延期が必要です。この種の「イベント」は実際にはコマンドです。たとえば、「マウスを動かした」というのは単なるイベントです。システムは、イベントを処理するかどうかを気にしません。ただし、「サスペンド」はコマンドです。システムは、コマンドから戻ると、サスペンドの準備が完了していると想定します。この場合、システムに戻ってきてもまだ完了していないことを通知するために延期が必要です。

async同様に、の実装を持つバックグラウンドタスクがある場合は、延期が必要ですRun。戻ったときRun、バックグラウンドタスクは完了したと見なされ、まだ実際には完了していないと言う方法が必要だからです。

メソッドの存在により、イベントハンドラーがこれをサポートしているかどうかを判断できますGetDeferral。たとえば、メソッドを持つプロパティがあるSuspendingため、延期をサポートします。バックグラウンドタスクシナリオ(つまり、があります)では、に渡されたを呼び出すことができます。SuspendingEventArgsSuspendingOperationGetDeferralasync void RunGetDeferralIBackgroundTaskInstanceRun

SelectAContactForASlotリターンの例Taskなので、延期する必要はありません。

于 2012-11-16T18:27:58.270 に答える