Tôi đang phát triển ứng dụng Windows Phone 8.1. Tôi có một màn hình với một danh sách các tiêu đề tin tức với hình thu nhỏ.Không đồng bộ/đang chờ bế tắc trong khi tải xuống hình ảnh
Trước tiên tôi đang làm theo yêu cầu http không đồng bộ để có được bộ sưu tập tin trong JSON (đáp ứng NotifyTaskCompletion
pattern)
NewsCategories = new NotifyTaskCompletion<ObservableCollection<NewsCategory>>(_newsService.GetNewsCategoriesAsync());
NewsCategory:
public class NewsCategory : ObservableObject
{
...
public string Title { get; set; }
public ObservableCollection<News> Items { get; set; }
}
Tin tức:
public class News : ObservableObject
{
...
public string Title { get; set; }
public string ImagePath { get; set; }
}
Cho đến nay nó hoạt động hoàn hảo, nhưng ngay sau khi tôi nhận được tài sản ImagePath
, tôi muốn tải xuống và hiển thị hình ảnh đã cho. Tôi đã tìm thấy một giải pháp để làm điều đó một cách không đồng bộ ở đây: WP 8.1 Binding image from a http request - để khi xaml nhận được đường dẫn hình ảnh, nó gọi một lớp chuyển đổi (BinaryToImageSourceConverter
), cũng sử dụng mẫu NotifyTaskCompletion
.
Vấn đề xảy ra trong phương pháp sau đây:
private async Task<BitmapImage> GetImage(string path)
{
HttpClient webCLient = new HttpClient();
var responseStream = await webCLient.GetStreamAsync(path);
var memoryStream = new MemoryStream();
await responseStream.CopyToAsync(memoryStream);
memoryStream.Position = 0;
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(memoryStream.AsRandomAccessStream());
return bitmap;
}
Khi await
đầu tiên được gọi, trình gỡ lỗi không bao giờ đạt dòng tiếp theo và các phương pháp không bao giờ trở lại. Biến số string path
có nội dung phù hợp.
Cho đến nay tôi đã cố gắng sử dụng ConfigureAwait(false)
, nhưng nó không hoạt động trong trường hợp của tôi.
Tôi cũng đã phát hiện ra trong topic: Deadlock while using async await, rằng:
Khi bạn đang sử dụng
ConfigureAwait(false)
, bạn cho chương trình của bạn, bạn không nhớ về bối cảnh. Nó có thể giải quyết một số vấn đề bế tắc, nhưng không phải là giải pháp đúng. Các giải pháp đúng là rất có thể không bao giờ chờ đợi cho các nhiệm vụ một cách ngăn chặn, và được không đồng bộ tất cả các cách.
Tôi không biết nơi tôi có thể có nội dung đó theo cách chặn. Điều gì có thể là lý do cho bế tắc đó?
Và nếu đó là tất cả về phương pháp tiếp cận sai, bạn có biết bất kỳ mẫu nào thích hợp hơn để tải hình thu nhỏ xuống một tập hợp các mục không?
Cảm ơn sự giúp đỡ của bạn.
update: như thế nào GetImage
gọi: Nó giống như trong chủ đề: WP 8.1 Binding image from a http request
public class WebPathToImage : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value == null) return null;
return new NotifyTaskCompletion<BitmapImage>(GetImage((String)value));
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{ throw new NotImplementedException(); }
private async Task<BitmapImage> GetImage(string path)
{
using (var webCLient = new HttpClient())
{
webCLient.DefaultRequestHeaders.Add("User-Agent", "bot");
var responseStream = await webCLient.GetStreamAsync(path).ConfigureAwait(false);
var memoryStream = new MemoryStream();
await responseStream.CopyToAsync(memoryStream);
memoryStream.Position = 0;
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(memoryStream.AsRandomAccessStream());
return bitmap;
}
}
}
và trong XAML:
<Image
DataContext="{Binding ImagePath, Converter={StaticResource WebPathToImage}}"
Source="{Binding Result}"
Stretch="UniformToFill"
Height="79" Width="79"/>
Cách gọi 'GetImage'? Hoặc bạn chặn nó bằng cách sử dụng '.Result' hoặc' .Wait'? –
Tôi đã chỉnh sửa bài đăng của mình để hiển thị mã. –
Tôi không trực tiếp thấy bất cứ điều gì có thể sai. Nếu bạn có thể tạo ra một bản sao nhỏ, nhỏ gọn, điều này sẽ giúp ích cho bạn. –