[英]Windows 8 - await Task<Bool> - async call back on completed listener required
我有一個函數,可以從存儲中打開文件,然后返回一個布爾值,該布爾值指定文件打開得很好。
private async Task<bool> SaveImage()
{
try
{
await filesave.openAsync(FileAccessMode.ReadWrite)
}
catch()
{
return false;
}
return true;
}
我想調用await SaveImage()函數,但是不知何故想要一個偵聽器/事件處理程序,它告訴我何時完成此操作。完成后,我想用新數據更新布局。 對於Windows 8,如何使用新的WINRT異步/等待異步方法來實現? 有沒有解決/替代的方法。
如何設置事件處理程序類型方案? (完成)
您只需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
的方法內。 如果該方法需要將其完成信號通知給其調用者,則它還應該返回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
的方法SaveImage
的末尾(例如,它是Button
的Click
事件的處理程序),那么它可以是async void
:
private async void ButtonClick(object sender, EventArgs args) {
var succeeded = await SaveImage();
if (succeeded) { ... }
}
Joe的回答看起來不錯,但是如果您堅持使用事件-例如,如果SaveImage()調用位於與更新布局無關的各個代碼區域中,則只需在操作完成后引發一個事件即可。 您可以使用普通的舊CLR事件,也可以使用發布- 訂閱 模式實現,例如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;
}
這需要花費更多的代碼,但是通常是處理異步操作,進度,取消和完整狀態的一種非常酷而有用的方法。 這是在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));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.