簡體   English   中英

Windows 8-等待任務 <Bool> -需要異步回調已完成的偵聽器

[英]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的方法內。 如果該方法需要將其完成信號通知給調用者,則它還應該返回TaskTask<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的末尾(例如,它是ButtonClick事件的處理程序),那么它可以是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM