当前位置:编程学习 > C#/ASP.NET >>

求 AutoResetEvent 在Form 的用法

AutoResetEvent waiter = new AutoResetEvent(false);

在某个事件中写
waiter.Set();
然后整个界面就卡死了。

在回调函数中写

((AutoResetEvent)e.UserState).Set();

也恢复不过来求解 --------------------编程问答-------------------- 贴代码出来看看撒,有可能是使用方法不对吧 --------------------编程问答-------------------- 事件是一个线程中的,当然找死。


同步对象指的是不同线程或者异步操作之间的同步 --------------------编程问答-------------------- 多线程编程尽量不要使用阻塞操作,用在主线程中胡写 WaitOne 等阻塞操作更是不行的。

应该总是使用异步操作的概念来编程,这需要从脑筋上去对知识进行更新,而不要总是使用并行操作的语法来模拟顺序操作。

如果实在是没有现成的异步操作方法可调用,那么你的主线程要开始一个操作时可以写类似
http://msdn.microsoft.com/zh-cn/library/kbf0f1ct(v=vs.100).aspx
这样的代码,也就是说你的主线程根本不阻塞。 --------------------编程问答-------------------- 我给你写两个代码,首先在一个窗体上拖入一个TextBox、一个Button、一个Label空间,然后试试代码:

其一
using System;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        ManualResetEvent eh = new ManualResetEvent(false);

        public Form1()
        {
            InitializeComponent();
        }

        private void a()
        {
            Thread.Sleep(10000);
            this.label1.BeginInvoke(new Action(() => this.label1.Text = DateTime.Now.ToString() + "刷新了界面!"));
            eh.Set();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            a();
            eh.WaitOne();
        }
    }
}


其二
using System;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void a()
        {
            Thread.Sleep(10000);
            this.label1.BeginInvoke(new Action(() => this.label1.Text = DateTime.Now.ToString() + "刷新了界面!"));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(h => a());
        }
    }
}

你可以看到第二种才不会阻塞界面上需要立刻响应的操作。第一种使用阻塞,虽然貌似是多线程编程,但是却失去了意义! --------------------编程问答-------------------- 至于你在主线程中先WaitOne阻塞,然后在主线程中妄图调用Set,这更不用说自然是极其低级的编程错误。这种错误都懒得去当作一个什么设计模式去谈论啦。

我给你写第三个程序
using System;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void a(Action callback)
        {
            Thread.Sleep(5000);
            this.label1.BeginInvoke(new Action(() =>
            {
                this.label1.Text = DateTime.Now.ToShortTimeString() + "第一次!";
                if (callback != null)
                    callback();
            }));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(h => a(b));
        }

        private void b()
        {
            Thread.Sleep(10000);
            this.label1.Text += "另一个程序被调用!";
        }
    }
}


你可以看到虽然我们把b给a让它处理完线程任务之后立刻继续调用b,但是此时主线程又被阻塞了。

凡是滥用阻塞的程序都很容易失去多线程编程的意义! --------------------编程问答--------------------
引用 3 楼 sp1234 的回复:
多线程编程尽量不要使用阻塞操作,用在主线程中胡写 WaitOne 等阻塞操作更是不行的。

应该总是使用异步操作的概念来编程,这需要从脑筋上去对知识进行更新,而不要总是使用并行操作的语法来模拟顺序操作。

如果实在是没有现成的异步操作方法可调用,那么你的主线程要开始一个操作时可以写类似
http://msdn.microsoft.com/zh-cn/library/kbf0f1ct(v=……

看明白了,谢谢你... 说得对,凡是滥用阻塞的程序都很容易失去多线程编程的意义!
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,