首页 新闻 会员 周边

PropertyChangedEventHandler的多线程问题

0
悬赏园豆:20 [已解决问题] 解决于 2014-01-02 16:23
public partial class Form1 : Form
    {
        public class Test : System.ComponentModel.INotifyPropertyChanged
        {
            private int m_Count = 0;
            public int Count
            {
                get { return m_Count; }
                set
                {
                    m_Count = value;
                    NotifyPropertyChanged("Count");
                }
            }

            public void Begin()
            {
                Thread thread = new Thread(Counter);
                thread.Start();
            }

            private void Counter()
            {
                for (int i = 0; i < 1000; i++)
                {
                    Count = i;
                    System.Threading.Thread.Sleep(100);
                }
            }

            public void NotifyPropertyChanged(string info)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(info));
                }
            }

            #region INotifyPropertyChanged 成员

            public event PropertyChangedEventHandler PropertyChanged;

            #endregion
        }

        public Form1()
        {
            InitializeComponent();
            Binding binding = new Binding("Text", t, "Count");
            label1.DataBindings.Add(binding);
        }

        Test t = new Test();

        private void button1_Click(object sender, EventArgs e)
        {
            t.Begin();
        }

    }

出现的错误是:线程间操作无效: 从不是创建控件“label1”的线程访问它。

 

请问如何解决呢?

luoshupeng的主页 luoshupeng | 初学一级 | 园豆:68
提问于:2014-01-01 21:40
< >
分享
最佳答案
0

在Form1中设 CheckForIllegalCrossThreadCalls = false;

public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
            Binding binding = new Binding("Text", t, "Count");
            label1.DataBindings.Add(binding);
        }
收获园豆:20
德年 | 小虾三级 |园豆:810 | 2014-01-02 09:40

除了这种方法,还有其它的方法吗?

如果我是用WPF界面呢?

luoshupeng | 园豆:68 (初学一级) | 2014-01-02 09:43

WPF中的Binding 支持跨线程,不存在这个问题。

还可以用BeginInvoke

 public partial class Form1 : Form
    {       
        public Form1()
        {
            InitializeComponent();
            t.UIElement = this;
            Binding binding = new Binding("Text", t, "Count");
            label1.DataBindings.Add(binding);
        }

        Test t = new Test();

        private void button1_Click(object sender, EventArgs e)
        {
            t.Begin();            
        }

    }

    public class Test : System.ComponentModel.INotifyPropertyChanged
    {
        private int m_Count = 0;
        public int Count
        {
            get { return m_Count; }
            set
            {
                m_Count = value;
                NotifyPropertyChanged("Count");
            }
        }

        public void Begin()
        {
            Thread thread = new Thread(Counter);
            thread.IsBackground = true;
            thread.Start();
        }

        private void Counter()
        {
            for (int i = 0; i < 1000; i++)
            {
                if (UIElement!=null&&UIElement.IsHandleCreated)
                {
                    UIElement.BeginInvoke((Action)(() => { Count = i; }));
                }
                System.Threading.Thread.Sleep(100);
            }
        }

        public void NotifyPropertyChanged(string info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        public Control UIElement { get; set; }



        #region INotifyPropertyChanged 成员

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
德年 | 园豆:810 (小虾三级) | 2014-01-02 11:52
其他回答(1)
0

调用invoke方法.可以将方法委托传回到UI线程执行.

这是微软的推荐方法,不要关闭线程安全检测,

吴瑞祥 | 园豆:29449 (高人七级) | 2014-01-02 10:27

关键是这个Invoke方法应该如何写,

我不会写啊,你能给出个例子吗?

支持(0) 反对(0) luoshupeng | 园豆:68 (初学一级) | 2014-01-09 09:12

@luoshupeng: http://msdn.microsoft.com/zh-cn/library/ms171728(v=vs.110).aspx

支持(0) 反对(0) 吴瑞祥 | 园豆:29449 (高人七级) | 2014-01-09 09:14

@吴瑞祥: 谢谢你给的回复,这个在线程中给控件赋值的委托方法我会用。

可是我现在的问题是绑定啊,你看看我的例子。

这个委托的Invoke不会写啊。

支持(0) 反对(0) luoshupeng | 园豆:68 (初学一级) | 2014-01-09 09:18

@luoshupeng: 上面那个写法是对的,需要把外面的UI控件传到test类里去.

支持(0) 反对(0) 吴瑞祥 | 园豆:29449 (高人七级) | 2014-01-09 09:31
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册