WPF - 线程和更改变量 [英] WPF - Threads and change variable

查看:34
本文介绍了WPF - 线程和更改变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 1 个简单线程的应用程序:

I have application with 1 simple thread:

 public partial class MainWindow : Window
    {    

        Thread historyThread = null;

        Window historyWindow = null;

        public MainWindow()
        {
            //...
        }

        #region EVENTS Magazyn
        private void btn_K_FinalizujZakup_Click(object sender, RoutedEventArgs e)
        {
            if (dg_Klient.Items.Count > 0)
            {
//Problem with 'Finalizuj' Method
                new Historia.Wpis(MainWindowViewModel.klient).Finalizuj(viewModel.historiaWindow_ViewModel.historiaZakupow);
                MainWindowViewModel.klient = new Klient.Klient();
                dg_Klient.ItemsSource = MainWindowViewModel.klient;
            }
        }

        #region History Thread
        private void btn_K_HistoriaOpen_Click(object sender, RoutedEventArgs e)
        {
            //if(historyThread != null){
            //    historyThread.Abort();
            //    historyThread = null;
            //}
            historyThread = new Thread(new ThreadStart(History_ThreadStart));
            historyThread.SetApartmentState(ApartmentState.STA);
            historyThread.IsBackground = true;
            historyThread.Start();
        }

        private void History_ThreadStart()
        {
            historyWindow = new HistoryWindow(viewModel.historiaWindow_ViewModel);
            historyWindow.Show();
            historyWindow.Activate();
            System.Windows.Threading.Dispatcher.Run();

        }
        #endregion // History Thread
        //...
    }

和'Wpis'类看起来像:

and 'Wpis' Class look like:

public class Wpis
{
    private DateTime date;
    public DateTime Date // normal get/ set

    private ObservableCollection<Produkt> listaZakupow;
    public ObservableCollection<Produkt> ListaZakupow // normal get/set

    public Wpis(ObservableCollection<Produkt> listaZakupow)
    {
        date = DateTime.Now;
        this.listaZakupow = listaZakupow;
    }

    public void Finalizuj(Historia historia)
    {
        //NOT! - Thread Safe

        // EXCEPTION!
        // NotSupportedException
        // This type of CollectionView does not support changes SourceCollection collection from a thread other than the Dispatcher.
        historia.Add(this);            
    }

    private void DoDispatchedAction(Action action)
    {
        if (currentDispatcher.CheckAccess())
        {
            action.Invoke();
        }
        else
        {
            currentDispatcher.Invoke(DispatcherPriority.DataBind, action);
        }
    }

}

当我不运行线程 (historyThread) 时,我可以正常执行多次方法Finalizuj"但是当我运行 Thread 时,我无法向列表添加任何内容(无法运行方法 - 'Finalizuj')并且 VS 向我展示了以下异常:

And when I don't run thread (historyThread) I can normal do method 'Finalizuj' many times but when I run Thread I can't add anything to list (can't run method - 'Finalizuj') And VS show me exception about:

NonSupportedException was unhandled
This type of CollectionView does not support changes SourceCollection collection from a thread other than the Dispatcher.

我真的不知道我做错了什么.我需要在我的项目中添加什么?

I dont really know what i do wrong. What i need to add to my project?

简而言之:在主线程中 - 我有 object_1 (typeof: ObservableCollection)在第二个线程中 - 我想将另一个对象(typeof:Wpis:ObservableCollection)添加到 object_1但我得到上述异常

In short: In main Thread - I have object_1 (typeof: ObservableCollection) In second Thread - I want add anothrer object (typeof: Wpis : ObservableCollection) to object_1 but I get the abovementioned exception

推荐答案

例外就是告诉你你需要做什么.您不能从不同的线程修改 UI.我假设您的 Observable 集合绑定在您的 XAML 中的某处.

The Exception is telling you exactly what you need to do. You cannot modify the UI from a different thread. I'm assuming that your Observable collection is bound somewhere in your XAML.

您需要获得对 MainWindow 类的引用,以便您可以访问 Dispatcher 线程.

You will need to obtain a reference to your MainWindow class so you can access the Dispatcher thread.

public static MainWindow Current { get; private set; }

        public MainWindow()
        {
            Current = this;
            //...
        }

然后使用 Dispatcher 线程修改您的集合:

Then use the Dispatcher thread to modify your collection:

        MainWindow.Current.Dispatcher.Invoke((Action)(() =>
        {
            historia.Add(this);
        }));

这篇关于WPF - 线程和更改变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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