Dispatcher.BeginInvoke(...)不调度任何内容

时间:2012-12-29 15:52:56

标签: c# wpf multithreading dispatcher begininvoke

我正在尝试从网络服务器获取大量图像,所以不要让每秒数百个请求超载服务器我只让少数通过WebService处理。以下代码位于保存图像的对象上,以及所有绑定所在的位置。

ThreadStart thread = delegate()
{
    BitmapImage image = WebService.LoadImage(data);

    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
    {
        this.Image = image;
    }));
};

new Thread(thread).Start();

图像加载得很好,UI在图像加载时流畅地工作,但永远不会调用this.Image = image。如果我使用Dispatcher.CurrentDispatcher.Invoke(..),则会调用该行,但不能用于设置图像。 为什么调度员不会调用我的动作?

2 个答案:

答案 0 :(得分:3)

由于您在工作线程上创建了BitmapImage,因此它不归WPF线程所有。 也许这段代码可以帮助您解决问题:

您发布的代码

ThreadStart thread = delegate()
{
    BitmapImage image = WebService.LoadImage(data, Dispatcher.CurrentDispatcher);

    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
    {
        this.Image = image;
    }));
};

new Thread(thread).Start();

如何将WebService.LoadImage更改为“使其正常工作”

BitmapImage LoadImage(object data, Dispatcher dispatcher)
{
    // get the raw data from a webservice etc.
    byte[] imageData = GetFromWebserviceSomehow(data);

    BitmapImage image;

    // create the BitmapImage on the WPF thread (important!)
    dispatcher.Invoke(new Action(()=>
    {
        // this overload does not exist, I just want to show that
        // you have to create the BitmapImage on the corresponding thread
        image = new BitmapImage(imageData);
    }));

    return image;
}

答案 1 :(得分:1)

System.Object
    |-> System.Windows.Threading.DispatcherObject
        |-> System.Windows.DependencyObject
            |-> System.Windows.Freezable
                |-> ... 
                    |-> System.Windows.Media.Imaging.BitmapImage

BitmapImage是线程约束的。因此,this控件和BitmapImage对象应该在同一个线程中创建。 你也可以尝试冻结图片,但似乎没有帮助。

BeginInvoke不会显示错误,因为它是由WPF处理的。请参阅MSDN如何设置WPF跟踪。

WPF是单线程的。阅读一些关于所有员工描述的WPF的书。