2012-08-30 15 views
4

我試圖用轉換器檢查本地存儲器中是否存在圖像源。如果沒有去與外部網址。如何在WinRT中創建文件存在轉換器

<Image Source="{Binding Image, Converter={StaticResource ImageCacheConverter}}"/>

這是我的轉換器至今:

public object Convert(object value, Type targetType, object parameter, string language) 
{ 
    return IfFileExist((string)value, "localimage.png"); 
} 
public async Task<string> IfFileExist(string value, string filename) 
{ 
    var folder = ApplicationData.Current.LocalFolder; 
    var getFilesAsync = await folder.GetFilesAsync(CommonFileQuery.OrderByName); 

    var file = getFilesAsync.FirstOrDefault(x => x.Name == filename); 
    if (file != null) 
    { 
     return "ms-appdata:///local/" + filename; 
    } 
    return (string)value; 
} 

我面對的是具有的IValueConverter內異步的主要問題。但我需要返回IfFileExist來更改圖像源。

在此先感謝。

+0

爲什麼'IfFileExist'' async'無論如何? –

+0

原因await folder.GetFilesAsync(CommonFileQuery.OrderByName); – nicruo

+3

您是否確定要將潛在的緩慢操作作爲綁定的一部分?如果文件被移動,我會緩存信息並添加一些錯誤處理。這種方法是「異步」的原因是有原因的! –

回答

4

我想你不想讓你的IfFileExist方法異步運行。但由於使用await,這就是發生了什麼。

嘗試更改爲此:

public async Task<System.Collections.Generic.IReadOnlyList<Windows.Storage.StorageFile>> GetFilesAsync() 
{ 
    var folder = ApplicationData.Current.LocalFolder; 
    return await folder.GetFilesAsync(CommonFileQuery.OrderByName) 
         .AsTask().ConfigureAwait(false); 
} 

public string IfFileExist(string value, string filename) 
{ 
    var files = GetFilesAsync().Result; 

    var file = files.FirstOrDefault(x => x.Name == filename); 
    if (file != null) 
    { 
     return "ms-appdata:///local/" + filename; 
    } 
    return value; 
} 

而不是使用await我們訪問受GetFilesAsync返回,擋住了我們的方法,直到任務完成的任務Result財產。

您的原始代碼是準等同於以下:

public async Task<string> IfFileExist(string value, string filename) 
{ 
    var folder = ApplicationData.Current.LocalFolder; 
    var getFilesAsync = folder.GetFilesAsync(CommonFileQuery.OrderByName); 

    return getFilesAsync.ContinueWith(z => 
    { 
     var file = getFilesAsync.FirstOrDefault(x => x.Name == filename); 
     if (file != null) 
     { 
      return "ms-appdata:///local/" + filename; 
     } 
     return (string)value; 
    } 
} 
+0

轉換器返回錯誤: 'await'操作符只能在異步方法中使用。考慮用'異步'修飾符標記此方法並將其返回類型更改爲'任務' – nicruo

+0

@nicruo:請參閱更新。 –

+0

A出現此錯誤: 'Windows.Foundation.IAsyncOperation >'不包含'Result'的定義,也沒有擴展方法'Result'接受第一個可以找到類型爲'Windows.Foundation.IAsyncOperation >'的參數(您是否缺少using指令或程序集引用?) – nicruo

3

的核心問題是,你需要一個同步操作(Convert)內做一個async操作。有沒有一個簡單的方法來做到這一點;如果可能的話,組織您的代碼,這樣就沒有必要(例如,有一個屬性啓動對「轉換」結果的另一個屬性的async更新)。

如果你想試圖迫使它適合,你必須使用ConfigureAwait(false)

public object Convert(object value, Type targetType, object parameter, string language) 
{ 
    // Note that "Result" will wrap any errors in AggregateException, which is annoying. 
    return IfFileExist((string)value, "localimage.png").Result; 
} 

public async Task<string> IfFileExist(string value, string filename) 
{ 
    var folder = ApplicationData.Current.LocalFolder; 
    var getFilesAsync = await folder.GetFilesAsync(CommonFileQuery.OrderByName) 
     .AsTask().ConfigureAwait(false); 

    var file = getFilesAsync.FirstOrDefault(x => x.Name == filename); 
    if (file != null) 
    { 
    return "ms-appdata:///local/" + filename; 
    } 
    return (string)value; 
} 
+0

得到此錯誤:'Windows.Foundation.IAsyncOperation >'不包含'StartAsTask'的定義,也沒有接受第一個參數的擴展方法'StartAsTask'的類型'Windows.Foundation.IAsyncOperation >'可以找到(你是否缺少使用指令或程序集引用?) – nicruo

+2

對不起 - MS更改了名稱。查看更新的答案。 –

+0

謝謝你。你導致正確的答案。丹尼爾希爾加斯釘了它。對不起,我不能把你們都當成正確的答案。 – nicruo

0

我沒有Windows 8靠近我,但現在我可以建議嘗試以下代碼(只Convert方法體):

public object Convert(object value, Type targetType, object parameter, string language) 
{ 
    string result = string.Empty; 
    Task.Run(async delegate 
    { 
     result = await IfFileExist((string)value, "localimage.png"); 
    }).Wait(); 

    return result; 
} 

我不知道,如果它的工作不過。

+0

嗨亞歷山大,對不起,我沒有回答你。我試了一下,但沒有奏效。不過謝謝你的時間。 – nicruo

相關問題