c# - WPF 线程和 GUI 如何从不同的线程访问对象?

标签 c# .net wpf

我有一个线程调用一个从 Internet 获取一些东西的对象。当此对象填满所需的所有信息时,它会引发一个事件,对象将包含所有信息。该事件由启动线程的 Controller 使用。

然后将事件返回的对象添加到一个集合中,该集合通过 View 模型方法绑定(bind)到 GUI。

问题是我无法将 CheckAccess 与绑定(bind)一起使用...如何解决使用从主线程的其他线程创建的对象的问题?

将对象添加到主线程集合时收到的错误是:

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

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

最佳答案

我找到了这个 blog 的解决方案.

而不是仅仅调用集合来从线程中添加对象。

queriesViewModel.AddQuery(info);

我必须将主线程传递给 Controller ​​并使用调度程序。守卫的回答非常接近。

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

关于c# - WPF 线程和 GUI 如何从不同的线程访问对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1261248/

相关文章:

c# - 在 DWM 玻璃下使用 TextBox 进行测试

c# - 在 C# 中使用 Powershell cmdlet 从 AzureAD 获取特定用户详细信息

java - 什么可能导致在 GZip 压缩数据流中创建错误的 EOF

c# - 命令在我的附加属性中获取 null 用于将事件转换为命令

c# - 如何以编程方式启用/禁用 IE 代理设置?

c# - Unity3d 从父源实例化一个子预制件

c# - 使用 PadRight 方法填充字符串

c# - 升级.Net版本后无法加载文件或程序集错误

wpf - 将样式资源分配给 DataGrid

wpf - 通过样式在 TextBox 上设置 WPF Binding.StringFormat 属性