WPF线程和GUI如何从不同的线程访问的对象? [英] WPF thread and GUI how to access object from different thread?

查看:103
本文介绍了WPF线程和GUI如何从不同的线程访问的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个称之为得到一些东西,从网络对象的线程。当这个目的是填充有所需的所有信息,它会引发与对象将所有的信息的事件。本次活动由已启动线程控制器消耗。

从事件返回的对象比加入,它通过查看模型的方法绑定的图形用户界面的集合。

现在的问题是,我不能使用的checkAccess与结合...我如何解决已从主之一的其他线程?

创建使用对象的问题

这是我收到的时候我的对象添加到主线程的集合中的错误是:

  

该类型的CollectionView不支持从一个线程更改其SourceCollection从调度线程不同。

这对控制器:

 公共类WebPingerController
{
    私人IAllQueriesViewModel queriesViewModel;

    私人PingerConfiguration配置;

    私人萍儿平;

    私人螺纹threadPing;

    公共WebPingerController(PingerConfiguration配置,IAllQueriesViewModel queriesViewModel)
    {
        this.queriesViewModel = queriesViewModel;
        this.configuration =配置;
        this.ping =新瓶儿(configuration.UrlToPing);
        this.ping.EventPingDone + =新delPingerDone(ping_EventPingDone);
        this.threadPing =新主题(新的ThreadStart(this.ThreadedStart));
    }


    无效ping_EventPingDone(对象发件人,QueryStatisticInformation信息)
    {
        queriesViewModel.AddQuery(信息); //错误发生在这里
    }

    公共无效启动()
    {
        this.threadPing.Start();
    }

    公共无效停止()
    {
        尝试
        {
            this.threadPing.Abort();
        }
        赶上(例外五)
        {

        }
    }

    私人无效ThreadedStart()
    {
        而(this.threadPing.IsAlive)
        {
            this.ping.Ping();
            Thread.sleep代码(this.configuration.TimeBetweenPing);
        }
    }
}
 

解决方案

我找到了解决方案,在这个的博客

而不是仅仅调用集合,从线程添加对象的

  queriesViewModel.AddQuery(信息);
 

我不得不主线程传递给控制器​​,并使用调度。后卫答案是十分密切的。

 公共委托无效MethodInvoker();
    无效ping_EventPingDone(对象发件人,QueryStatisticInformation信息)
    {
        如果(UIThread!= NULL)
        {

            Dispatcher.FromThread(UIThread).Invoke((MethodInvoker)代表
            {
                queriesViewModel.AddQuery(信息);
            }
            , 空值);
        }
        其他
        {
            queriesViewModel.AddQuery(信息);
        }
    }
 

I have a thread that call an object that get some stuff from Internet. When this object is filled up with all information required, it raises an event with an object will all the information. The event is consumed by the controller that has started the thread.

The returned object from the event is than added into a collection that is binded the the GUI via a View Model approach.

The problem is that I can't use the CheckAccess with the binding... how can I fix the problem of using Object that has been created from an other thread of the main one?

The error that I receive when I add the object to the collection of the main thread is :

This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

This the the controller:

public class WebPingerController
{
    private IAllQueriesViewModel queriesViewModel;

    private PingerConfiguration configuration;

    private Pinger ping;

    private Thread threadPing;

    public WebPingerController(PingerConfiguration configuration, IAllQueriesViewModel queriesViewModel)
    {
        this.queriesViewModel = queriesViewModel;
        this.configuration = configuration;
        this.ping = new Pinger(configuration.UrlToPing);
        this.ping.EventPingDone += new delPingerDone(ping_EventPingDone);
        this.threadPing = new Thread(new ThreadStart(this.ThreadedStart));
    }


    void ping_EventPingDone(object sender, QueryStatisticInformation info)
    {
        queriesViewModel.AddQuery(info);//ERROR HAPPEN HERE
    }

    public void Start()
    {
        this.threadPing.Start();
    }

    public void Stop()
    {
        try
        {
            this.threadPing.Abort();
        }
        catch (Exception e)
        {

        }
    }

    private void ThreadedStart()
    {
        while (this.threadPing.IsAlive)
        {
            this.ping.Ping();
            Thread.Sleep(this.configuration.TimeBetweenPing);
        }
    }
}

解决方案

I found the solution over this blog.

Instead of just calling the collection to add the object from the thread.

queriesViewModel.AddQuery(info);

I have to pass the main thread to the controller and use the dispatcher. Guard answer's was very close.

    public delegate void MethodInvoker();
    void ping_EventPingDone(object sender, QueryStatisticInformation info)
    {
        if (UIThread != null)
        {

            Dispatcher.FromThread(UIThread).Invoke((MethodInvoker)delegate
            {
                queriesViewModel.AddQuery(info);
            }
            , null);
        }
        else
        {
            queriesViewModel.AddQuery(info);
        } 
    }

这篇关于WPF线程和GUI如何从不同的线程访问的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆