求 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,但是此时主线程又被阻塞了。
凡是滥用阻塞的程序都很容易失去多线程编程的意义! --------------------编程问答--------------------
看明白了,谢谢你... 说得对,凡是滥用阻塞的程序都很容易失去多线程编程的意义!
补充:.NET技术 , C#