RunAsync
待機できる独自の非同期メソッドで呼び出しをラップし、タスクの完了を制御して、呼び出し元の待機を継続することができます。
async-await は型に集中しているためTask
、この型を使用して作業を調整する必要があります。ただし、通常はTask
スレッドプール スレッドで実行するようにスケジュールされるため、UI 作業のスケジュールには使用できません。
ただし、このTaskCompletionSource
タイプは、予定外のTask
. 言い換えると、 aは何もスケジュールされていないTaskCompletionSource
ダミーを作成できますが、 can のメソッドを介して、通常のジョブのように実行および完了しているように見えます。Task
TaskCompletionSource
この例を参照してください。
public Task PlayDemoAsync()
{
var completionSource = new TaskCompletionSource<bool>();
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
try
{
foreach (var ppc in this.Plots.Select(p => this.TransformPlot(p, this.RenderSize)))
{
// For each subsequent stroke plot, we need to start a new figure.
//
if (this.Sketch.DrawingPoints.Any())
this.Sketch.StartNewFigure(ppc.First().Position);
foreach (var point in ppc)
{
await Task.Delay(100);
this.Sketch.DrawingPoints.Add(point.Position);
}
}
completionSource.SetResult(true);
}
catch (Exception e)
{
completionSource.SetException(e);
}
});
return (Task)completionSource.Task;
}
注: UI スレッドで行われている主な作業は、100 ミリ秒ごとに画面に描画される線だけです。
ATaskCompletionSource
がパペット マスターとして作成されます。Task
最後の方を見ると、呼び出し元に返されるプロパティがあることがわかります。戻るTask
ことでコンパイラのニーズが満たされ、メソッドが待機可能になり、非同期になります。
ただし、これTask
は単なる操り人形であり、UI スレッドで行われている実際の作業のプロキシです。
そのメイン UI デリゲートでメソッドを使用して(呼び出し元に返されたので)TaskCompletionSource.SetResult
結果を に強制し、作業が完了したことを伝える方法を確認してください。Task
エラーが発生した場合は、SetException
「別の文字列をプル」して、パペットで例外が発生したように見せますTask
。
async-await サブシステムは違いを認識していないため、期待どおりに機能します。
編集
svick が促したように、メソッドが UI スレッドからのみ呼び出せるように設計されている場合、これで十分です。
/// <summary>
/// Begins a demonstration drawing of the asterism.
/// </summary>
public async Task PlayDemoAsync()
{
if (this.Sketch != null)
{
foreach (var ppc in this.Plots.Select(p => this.TransformPlot(p, this.RenderSize)))
{
// For each subsequent stroke plot, we need to start a new figure.
//
if (this.Sketch.DrawingPoints.Any())
this.Sketch.StartNewFigure(ppc.First().Position);
foreach (var point in ppc)
{
await Task.Delay(100);
this.Sketch.DrawingPoints.Add(point.Position);
}
}
}
}