如果图像尚未本地存储,我有一个应用程序正在从服务器下载图像并将它们存储在本地。为了这个例子,假设我有许多同名的图像。我只想下载一次并存储一次。目前,我的应用程序每次请求时都在下载它们 - 为了参数 10 向服务器发出的 imageX.png 请求。当请求返回时,应用程序会尝试将它们作为 imageX.png 存储在应用程序数据文件夹中。这是我的问题开始的地方,因为多个线程试图同时写入同一个文件。
这是我目前拥有的代码
public static async Task<BitmapImage> GetBitmapImage( string folderName, string fileName )
{
if( await FileExists( "\\Assets\\" + folderName, fileName ) )
{
return new BitmapImage( new Uri( Package.Current.InstalledLocation.Path + "/Assets/" + folderName + "/" + fileName, UriKind.RelativeOrAbsolute ) );
}
else
{
// Download and save locally
HttpClient httpClient = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage( HttpMethod.Get, "http://www.mywebsite.com/request.php?action=getImage&name=" + WebUtility.UrlEncode( fileName ) );
HttpResponseMessage response = await httpClient.SendAsync( request, HttpCompletionOption.ResponseHeadersRead );
BitmapImage image = new BitmapImage();
if( response.IsSuccessStatusCode )
{
InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
DataWriter writer = new DataWriter( randomAccessStream.GetOutputStreamAt( 0 ) );
writer.WriteBytes( await response.Content.ReadAsByteArrayAsync() );
await writer.StoreAsync();
await image.SetSourceAsync( randomAccessStream );
var folderObj = await StorageFolder.GetFolderFromPathAsync( Package.Current.InstalledLocation.Path + "\\Assets\\" + folderName );
var imageFile = await folderObj.CreateFileAsync( fileName, CreationCollisionOption.ReplaceExisting );
var fs = await imageFile.OpenAsync( FileAccessMode.ReadWrite );
writer = new DataWriter( fs.GetOutputStreamAt( 0 ) );
writer.WriteBytes( await response.Content.ReadAsByteArrayAsync() );
await writer.StoreAsync();
writer.DetachStream();
await fs.FlushAsync();
}
return image;
}
}
我怀疑我需要的是在“如果 FileExists”之前停止线程,直到前一个线程完成其任务并在必要时保存到磁盘。然后,其余线程将在 FileExists 调用上立即返回 true 有人可以在这里指出我正确的方向吗?