Sunday, December 29, 2013

How to update controls from another thread?

namespace WpfApplication1
{
    class Stock
    {
        public int StockId { get; set; }
        public string Name { get; set; }
    }

    class ThreadManager
    {
        public AddMoscowItem MoscowDelegate { get; set; }
        public AddLondonItem LondonDelegate { get; set; }
        public AddNewYorkItem NyDelegate { get; set; }

        public ThreadManager()
        {
            InitStocks();
        }

        private static  readonly object  lockObject = new object();

        private  Stock[] stocks;

        public ThreadManager(AddMoscowItem moscowDelegate, AddLondonItem londonDelegate, AddNewYorkItem nyDelegate)
        {
            MoscowDelegate = moscowDelegate;
            LondonDelegate = londonDelegate;
            NyDelegate = nyDelegate;
        }

        private void InitStocks()
        {
            if (stocks == null)
                lock (lockObject)
                {
                    if (stocks == null)
                        stocks = new Stock[]
                                     {
                                         new Stock() {Name = "Moscow", StockId = 1},
                                         new Stock() {Name = "London", StockId = 2},
                                         new Stock() {Name = "NY", StockId = 3}
                                     };
                }
        }

        public void RunStocks()
        {
            //here we must call methods: AddMoscowListBoxItem, AddLondonListBoxItem
            //how to do it linking to corresponding stock?
        }
    }

    public delegate void AddMoscowItem(string msg);
    public delegate void AddLondonItem(string msg);
    public delegate void AddNewYorkItem(string msg);

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private AddMoscowItem moscowDelegate;
        private AddLondonItem londonDelegate;
        private AddNewYorkItem nyDelegate;

        public MainWindow()
        {
            InitializeComponent();

            moscowDelegate = AddMoscowListBoxItem;
            londonDelegate = AddLondonListBoxItem;
            nyDelegate = AddNYListBoxItem;
            RunThreads();
        }

        public void RunThreads()
        {
            ThreadManager stockThreads = new ThreadManager(moscowDelegate, londonDelegate, nyDelegate);
            stockThreads.RunStocks();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

        }

        public void AddMoscowListBoxItem(string msg)
        {
            if (this.lbxMoscow.Dispatcher.Thread == Thread.CurrentThread)
            {
               lbxMoscow.Items.Add(msg);
            }
            else
            {
                lbxMoscow.Dispatcher.Invoke(DispatcherPriority.Background, new DispatcherOperationCallback(
                                            delegate { lbxMoscow.Items.Add(msg);
                                                         return null;
                                            }), null);
            }
        }

        public void AddLondonListBoxItem(string msg)
        {
            if (this.lbxLondon.Dispatcher.Thread == Thread.CurrentThread)
            {
                lbxLondon.Items.Add(msg);
            }
            else
            {
                lbxLondon.Dispatcher.Invoke(DispatcherPriority.Background, new DispatcherOperationCallback(
                                            delegate
                                            {
                                                lbxLondon.Items.Add(msg);
                                                return null;
                                            }), null);
            }
        }

        public void AddNYListBoxItem(string msg)
        {
            if (this.lbxNY.Dispatcher.Thread == Thread.CurrentThread)
            {
                lbxNY.Items.Add(msg);
            }
            else
            {
                lbxNY.Dispatcher.Invoke(DispatcherPriority.Background, new DispatcherOperationCallback(
                                            delegate
                                            {
                                                lbxNY.Items.Add(msg);
                                                return null;
                                            }), null);
            }
        }
    }
}
http://stackoverflow.com/questions/6511224/how-to-update-controls-from-another-thread