在WPF中使用线程对我没有什么影响。UI仍然没有响应。
这是我的密码:
private void button1_Click_1(object sender, RoutedEventArgs e)
{
Thread th = new Thread(new ThreadStart(LoadImages));
th.Start();
}
void LoadImages()
{
this.Dispatcher.Invoke(DispatcherPriority.Normal, new System.Windows.Forms.MethodInvoker(delegate() {
IService1 svc = ConnectAndGetObject();
foreach (byte[] imgbytes in svc.GetImageDateWise(datePicker1.DisplayDate, DateTime.Now, "test"))
{
using (MemoryStream mem = new MemoryStream(imgbytes))
{
BitmapImage jpgimage = new BitmapImage();
jpgimage.BeginInit();
jpgimage.CacheOption = BitmapCacheOption.OnLoad;
jpgimage.StreamSource = mem;
jpgimage.EndInit();
// PngBitmapDecoder decodejpg = new PngBitmapDecoder(mem, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnDemand);
Image wpfimage = new Image();
wpfimage.Source = jpgimage.Clone();
lbx.Items.Add(wpfimage);
lbx.UpdateLayout();
Thread.Sleep(1000);
}
}
}));
}更新工作代码:
List<MemoryStream> mems = new List<MemoryStream>();
void LoadImages()
{
IService1 svc = ConnectAndGetObject();
foreach (byte[] imgbytes in svc.GetImageDateWise(GetDate(), DateTime.Now, "test"))
{
this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate() {
mems.Add(new MemoryStream(imgbytes));
BitmapImage jpgimage = new BitmapImage();
jpgimage.BeginInit();
jpgimage.CacheOption = BitmapCacheOption.None;
jpgimage.StreamSource = mems[mems.Count-1];
jpgimage.EndInit();
Image wpfimage = new Image();
wpfimage.Source = jpgimage.Clone();
lbx.Items.Add(wpfimage);
lbx.UpdateLayout();
Thread.Sleep(500);
}));
}
mems.Clear();
}发布于 2010-01-01 17:39:45
在您的代码中,整个LoadImages主体被调用回主线程。因此,您根本没有多线程解决方案,只是一个复杂的解决方案。
这是我的刺:
// untested
void LoadImages()
{
// this.Dispatcher.Invoke(DispatcherPriority.Normal,
// new System.Windows.Forms.MethodInvoker(delegate() {
IService1 svc = ConnectAndGetObject();
foreach (byte[] imgbytes in svc.GetImageDateWise(datePicker1.DisplayDate, DateTime.Now, "test"))
{
using (MemoryStream mem = new MemoryStream(imgbytes))
{
BitmapImage jpgimage = new BitmapImage();
jpgimage.BeginInit();
jpgimage.CacheOption = BitmapCacheOption.OnLoad;
jpgimage.StreamSource = mem;
jpgimage.EndInit();
// only invoke the part actually touching the UI
this.Dispatcher.Invoke(DispatcherPriority.Normal,
new System.Windows.Forms.MethodInvoker(delegate() {
Image wpfimage = new Image();
wpfimage.Source = jpgimage; //.Clone();
lbx.Items.Add(wpfimage);
lbx.UpdateLayout(); } ));
Thread.Sleep(1000);
}
}
// }));
}发布于 2010-01-01 17:42:36
问题是,非UI线程所做的第一件事就是在UI线程上调用一个委托。最终的结果是大量开销,根本没有并发性。
重新组织代码,以便只在UI线程上执行UI任务。
void LoadImages()
{
IService1 svc = ConnectAndGetObject();
...
Dispatcher.Invoke( () => lbx.Items.Add(wpfimage));
....
} 发布于 2010-01-01 17:28:50
你的代表做得太多了。这可能是你的问题的原因,再加上你有1秒的睡眠时间。
只需要更新委托中的列表框的代码:
lbx.Items.Add(wpfimage);
lbx.UpdateLayout();如果失败,则会在线程中引发事件,并在主应用程序中订阅该事件,并由此更新UI。
您需要一个这样的方法:
private void ImageAdded_EventHandler(object sender, ImageAddedEventArgs e)
{
Action action = () => ImageAdded(e.Image);
if (Dispatcher.CheckAccess())
{
action();
}
else
{
Dispatcher.Invoke(DispatcherPriority.Normal, action);
}
}其中ImageAddedEventArgs是一个基于EventArgs的类,它具有图像数据的属性。
https://stackoverflow.com/questions/1989097
复制相似问题