WPF-поток и GUI, как получить доступ к объекту из другого потока? - PullRequest
6 голосов
/ 11 августа 2009

У меня есть поток, который вызывает объект, который получает некоторые вещи из Интернета. Когда этот объект заполняется всей необходимой информацией, он вызывает событие, при котором объект получает всю информацию. Событие используется контроллером, запустившим поток.

Возвращенный объект из события затем добавляется в коллекцию, которая привязывается к графическому интерфейсу с помощью подхода View Model.

Проблема в том, что я не могу использовать CheckAccess с привязкой ... как я могу решить проблему использования объекта, который был создан из другого потока основного?

Ошибка, которую я получаю, когда добавляю объект в коллекцию основного потока:

Этот тип CollectionView не поддерживает изменения в его SourceCollection из потока, отличного от потока Dispatcher.

Это контроллер:

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);
        }
    }
}

Ответы [ 2 ]

6 голосов
/ 11 августа 2009

Я нашел решение по этому блогу .

Вместо того, чтобы просто вызывать коллекцию, чтобы добавить объект из потока.

queriesViewModel.AddQuery(info);

Я должен передать основной поток контроллеру и использовать диспетчер. Ответ гвардии был очень близок.

    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);
        } 
    }
3 голосов
/ 11 августа 2009

Может ли быть решение инициализировать объект в главном потоке?

MyObject obj;

this.Dispatcher.Invoke((Action)delegate { obj = new MyObject() });

Редактировать : При повторном прочтении это, вероятно, не решение для вашей модели. Вы получаете ошибку во время выполнения как есть? Если объект, который вы передаете обратно, принадлежит вам, то обеспечение его поточности может сделать CheckAccess ненужным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...