求 AutoResetEvent 在Form 的用法 AutoResetEvent waiter = new AutoResetEvent(false);在某个事件中写waiter.Set();然后整个界面就卡死了。在回调函数中写((AutoResetEvent)e.UserState).Set();也恢复不过来求解 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 多线程编程尽量不要使用阻塞操作,用在主线程中胡写 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,但是此时主线程又被阻塞了。凡是滥用阻塞的程序都很容易失去多线程编程的意义! WPF:求教如何注销一个控件上的指定事件? 打印的一个小问题,如何打印内容縮放10%? 怎样隐藏datagridview的行标题和列标题? 高分求解 httpWebRequest 问题 .DLL .PDB文件怎么打开?寻找VB.NET高手 简单的问题,如何从string中读取一个float 请大家推荐几本除了MSDN外比较好的C#电子书 CacheItemRemovedCallBack的命名空间是什么? 跪求!关于邮箱格式的正则表达式的问题 何处有msil的帮助下载? C#实现窗体中所有控件跟随窗体尺寸的自由变换 新手求助:怎样改变datagridview的显示值?
http://msdn.microsoft.com/zh-cn/library/kbf0f1ct(v=vs.100).aspx
这样的代码,也就是说你的主线程根本不阻塞。
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());
}
}
}你可以看到第二种才不会阻塞界面上需要立刻响应的操作。第一种使用阻塞,虽然貌似是多线程编程,但是却失去了意义!
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,但是此时主线程又被阻塞了。凡是滥用阻塞的程序都很容易失去多线程编程的意义!