WPF - 线程和更改变量

时间:2014-12-31 14:29:15

标签: c# wpf multithreading

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

 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'类看起来像:

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)时,我可以正常地做方法&#39; Finalizuj&#39;多次 但是当我运行Thread时,我无法在列表中添加任何内容(无法运行方法 - &#39; Finalizuj&#39;) VS给我看了例外:

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

我真的不知道自己做错了什么。 我需要添加到我的项目中吗?

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

1 个答案:

答案 0 :(得分:1)

异常正在告诉你你需要做什么。您无法从其他线程修改UI。我假设您的Observable集合绑定在XAML中的某个位置。

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

public static MainWindow Current { get; private set; }

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

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

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