Windows 8 - 等待 Task<Bool> - 需要对已完成的侦听器进行异步回调
Posted
技术标签:
【中文标题】Windows 8 - 等待 Task<Bool> - 需要对已完成的侦听器进行异步回调【英文标题】:Windows 8 - await Task<Bool> - async call back on completed listener required 【发布时间】:2012-08-03 01:13:54 【问题描述】:我有一个函数,它从存储中打开一个文件并返回一个布尔值,指定文件打开得很好。
private async Task<bool> SaveImage()
try
await filesave.openAsync(FileAccessMode.ReadWrite)
catch()
return false;
return true;
我想调用 await SaveImage() 函数,但不知何故想要一个侦听器/事件处理程序,它告诉我何时完成。完成后我想用新数据更新我的布局。使用适用于 Windows 8 的新 WINRT 异步/等待异步方法如何实现这一点?是否有解决方法/替代方法。
如何设置事件处理程序类型方案? (完成)
【问题讨论】:
【参考方案1】:这需要更多的代码,但它是处理异步操作、进度、取消和完成状态的一种非常酷且有用的方法。这是在 VS2012 Winrt Store 应用程序中编译的,我通过单击按钮运行它,如您在此处看到的。
private void Save_File_Click(object sender, RoutedEventArgs e)
// create your op, bool = return type, string = progress report
IAsyncOperationWithProgress<bool, string> op;
// Call our async operation with progress sending the file name
op = OpenFileWithProgress("test.txt");
// not implemented here
//op.Cancel();
// when we get a progress update...
op.Progress = (info, progress) =>
// I'm just giving text feed back to user here
Debug.WriteLine(progress);
;
op.Completed = (info, status) =>
// check status for completion or cancellation...
switch (status)
case AsyncStatus.Completed:
// Do your completed work here
Debug.WriteLine("Completed");
break;
case AsyncStatus.Canceled:
// Operation canceled - not implemented...
Debug.WriteLine("Canceled");
break;
default:
// default stuff here
break;
;
public IAsyncOperationWithProgress<bool, string> OpenFileWithProgress(string fileName)
return System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.Run<bool, string>((token, progress) =>
Task.Run<bool>(async () =>
progress.Report("Starting");
try
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(fileName);
catch (Exception ex)
return false;
progress.Report("Finished");
return true;
, token));
【讨论】:
【参考方案2】:Joe 的回答看起来很棒,但如果您坚持使用事件 - 例如,如果您的 SaveImage() 调用位于与更新布局无关的各个代码区域 - 您可以在操作完成时引发事件。您可以使用普通的旧 CLR 事件或使用 pub-sub pattern 实现,例如 Prism 的 EventAggregator 或 MVVM Light 的 Messenger。 POCE 版本可能是这样的
public event EventHandler<Tuple<StorageFile,bool>> SaveImageCompleted;
private async Task<bool> SaveImage(StorageFile file)
try
await file.OpenAsync(FileAccessMode.ReadWrite);
catch
if (SaveImageCompleted != null)
SaveImageCompleted(this, new Tuple<StorageFile, bool>(file, false));
return false;
if (SaveImageCompleted != null)
SaveImageCompleted(this, new Tuple<StorageFile, bool>(file, true));
return true;
【讨论】:
【参考方案3】:您只需await
调用您的方法,然后在其后面加上完成后应该运行的代码。您无需手动注册事件处理程序。
var succeeded = await SaveImage();
// Because of the "await" keyword in the above line, the current method
// will not continue until "SaveImage" has completed its async work and
// signaled its Task
if (succeeded) ...
当然,由于上面的代码使用了await
关键字,因此需要将它放在一个也标记为async
的方法中。如果该方法需要向 its 调用者发出完成信号,那么它还应该返回一个Task
或Task<T>
;例如:
private async Task<string> MyHelperMethod()
var succeeded = await SaveImage();
if (succeeded)
return "Success";
else
return "Failure";
// then, in some other method:
var message = await MyHelperMethod();
或者,如果调用SaveImage
的方法是行尾——假设它是Button
的Click
事件的处理程序——那么它可以是async void
:
private async void ButtonClick(object sender, EventArgs args)
var succeeded = await SaveImage();
if (succeeded) ...
【讨论】:
注意:尽管方法中的其余行等待等待的方法完成,但调用该方法的方法将获得控制流执行。见msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx以上是关于Windows 8 - 等待 Task<Bool> - 需要对已完成的侦听器进行异步回调的主要内容,如果未能解决你的问题,请参考以下文章