繁体   English   中英

尽管进程在单独的线程中运行,但WPF UI没有响应。 为什么?

[英]WPF UI not responsive in spite of process running in a seperate thread. Why?

在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();


        }

在您的代码中, 整个 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);
        }
    }    
   //  }));
}

问题在于,非UI线程要做的第一件事是在UI线程上调用委托。 最终结果是大量的开销,根本没有并发。

重新组织代码,以便仅UI任务在UI线程上完成。

void LoadImages() 
{ 
    IService1 svc = ConnectAndGetObject(); 
...
Dispatcher.Invoke( () => lbx.Items.Add(wpfimage));
....
} 

您在代表中做得太多。 这可能是导致您出现问题的原因,再加上在那里停留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的类,该类具有图像数据的属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM