我正在编写 Windows Phone 应用程序,但无法理解模拟器崩溃的原因。它说:“ 0x773415de
XDE.exe 中未处理的异常0xC0000005
::访问冲突读取位置0x05190000
。” 仅当我开始快速滚动列表框时才会出现此问题。我将每 20 个项目加载到列表框(所有项目的数量为 200)。问题出在我的下载图像类中。我为每个图像创建一个 Webclient 请求到服务器还是创建一个线程池更好?
在 XAML 中:
<Image Name="userPic" Margin="0,8,1,2"
DelayFix:LowProfileImageLoader.UriSource="{Binding photoUrl}" Stretch="Fill"
Width="60"
Height="60"/>
下载图片类:
using System;
using System.Net;
using System.Windows.Resources;
using System.Windows.Media.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Phone;
using System.Diagnostics;
namespace PhoneApp
{
public class downloadImage
{
public int ImageIndex;
public string ImageURL;
public Boolean Downloaded;
public BitmapImage Bitmap;
public Image destinationImage;
private WebClient client;
public delegate void FileCompleteHandler(object sender);
public event FileCompleteHandler FileCompleteEvent;
private static readonly object _syncBlock = new object();
public downloadImage(int index, string imageURL, Image destinationImage = null)
{
this.ImageIndex = index;
this.ImageURL = imageURL;
this.destinationImage = destinationImage;
}
public void Download()
{
client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
client.OpenReadAsync(new Uri(this.ImageURL, UriKind.Absolute));
}
private void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null && e.Result != null)
{
Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
{
StreamResourceInfo sri = new StreamResourceInfo(e.Result as Stream, null);
if (destinationImage == null)
{
this.Bitmap = new BitmapImage();
this.Bitmap.SetSource(sri.Stream);
}
else
{
this.destinationImage.Source = PictureDecoder.DecodeJpeg(e.Result);
}
this.Downloaded = true;
if (FileCompleteEvent != null)
FileCompleteEvent(this);
}));
}
}
}
}
我班的代码:
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.Diagnostics;
using System.ComponentModel;
using Microsoft.Phone;
using Microsoft.Phone.Info;
namespace DelayFix
{
/// <summary>
/// Provides access to the Image.UriSource attached property which allows
/// Images to be loaded by Windows Phone with less impact to the UI thread.
/// </summary>
public static class LowProfileImageLoader
{
private static readonly object _syncBlock = new object();
private static bool _exiting;
/// <summary>
/// Gets the value of the Uri to use for providing the contents of the Image's Source property.
/// </summary>
/// <param name="obj">Image needing its Source property set.</param>
/// <returns>Uri to use for providing the contents of the Source property.</returns>
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "UriSource is applicable only to Image elements.")]
public static Uri GetUriSource(Image obj)
{
if (null == obj)
{
throw new ArgumentNullException("obj");
}
return (Uri)obj.GetValue(UriSourceProperty);
}
/// <summary>
/// Sets the value of the Uri to use for providing the contents of the Image's Source property.
/// </summary>
/// <param name="obj">Image needing its Source property set.</param>
/// <param name="value">Uri to use for providing the contents of the Source property.</param>
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "UriSource is applicable only to Image elements.")]
public static void SetUriSource(Image obj, Uri value)
{
if (null == obj)
{
throw new ArgumentNullException("obj");
}
obj.SetValue(UriSourceProperty, value);
}
/// <summary>
/// Identifies the UriSource attached DependencyProperty.
/// </summary>
public static readonly DependencyProperty UriSourceProperty = DependencyProperty.RegisterAttached(
"UriSource", typeof(Uri), typeof(LowProfileImageLoader), new PropertyMetadata(OnUriSourceChanged));
/// <summary>
/// Gets or sets a value indicating whether low-profile image loading is enabled.
/// </summary>
public static bool IsEnabled { get; set; }
[SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Static constructor performs additional tasks.")]
static LowProfileImageLoader()
{
Debug.WriteLine("Limit Memory:" + DeviceStatus.ApplicationMemoryUsageLimit / 1024 / 1024);
}
private static void HandleApplicationExit(object sender, EventArgs e)
{
Debug.WriteLine("Exit!");
}
private static void OnUriSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
lock (_syncBlock)
{
var image = (Image)o;
var uri = (Uri)e.NewValue;
Debug.WriteLine("Memory:" + DeviceStatus.ApplicationCurrentMemoryUsage / 1024 / 1024);
if (DesignerProperties.IsInDesignTool || !uri.IsAbsoluteUri)
{
image.Source = PhoneAppVKContest.ImageUtils.getJpegImage(uri.OriginalString);
}
else
{
PhoneAppVKContest.downloadImage di = new PhoneAppVKContest.downloadImage(0, uri.AbsoluteUri);
di.destinationImage = image;
di.FileCompleteEvent += new PhoneAppVKContest.downloadImage.FileCompleteHandler(di_FileCompleteEvent);
di.Download();
}
}
}
static void di_FileCompleteEvent(object sender)
{
Debug.WriteLine("Download success!");
}
}
}