C#多线程、跨线程与线程安全的示例详解(三种不同方法)
代码如下 | 复制代码 |
using System.Threading; public static class Extensions { //控件扩展方法(用于跨线程操作),因为为了线程的安全,防止资源竞争出现死锁或不一致的状态,.NET是不允许进行跨线程访问窗体控件的。 public static void SafeCall(this Control ctrl, Action callback) { if (ctrl.InvokeRequired) { ctrl.Invoke(callback); } else { callback(); } } } public partial class Form1 : Form { public Form1() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false;//方法二(禁用异常,不检查跨线程调用的安全问题,可以自由拖动窗体,不过在严格条件下也不可取,数据可能不一致) //方法三(推荐使用) //把你要保护起来的代码作为一个回调,然后任何需要保护一些代码的地方都可以这样调用 ThreadPool.QueueUserWorkItem(h => { int i = 0; while (true) { //如果没有SafeCall方法,将出现“线程间操作无效: 从不是创建控件“textBox1”的线程访问它。”的错误 ////匿名委托 //textBox1.SafeCall(delegate() //{ // textBox1.Text = (i++).ToString(); //}); //Lambda表达式 textBox1.SafeCall(() => { textBox1.Text = (i++).ToString(); }); //Thread.Sleep(100); } }); } //抽奖示例 public bool flag = true; public void choujiang() { flag = true; while (flag) { Random rnd = new Random(); textBox1.Text = rnd.Next(1, 100).ToString(); //Application.DoEvents();//方法一:这样也可以防止UI界面线程的阻塞,不至于被卡死。但是在拖动界面或其他操作的时候,程序会被暂停 } } //开始 private void button1_Click(object sender, EventArgs e) { //choujiang();//方法一 new Action(choujiang).BeginInvoke(null, null);//方法二 } //暂停 private void button2_Click(object sender, EventArgs e) { flag = false; } } |
异步线程池
代码如下 | 复制代码 |
delegate double weituo(double d); static weituo w = new weituo(perimeter); /// <summary> /// 计算周长 /// </summary> /// <param name="d"></param> public static double perimeter(double d) { return d * Math.PI; } /// <summary> /// 异步完成后回调的方法 /// </summary> /// <param name="result"></param> public static void method(IAsyncResult result) { Console.Write("hi~"); Console.WriteLine(w.EndInvoke(result)); } static void Main(string[] args) _________________________________ |
总结
优点:
·使用线程可以把占据长时间的程序中的任务放到后台去处理
·用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
·程序的运行速度可能加快
·在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。
缺点:
·如果有大量的线程,会影响性能,因为操作系统需要在他们之间切换;
·更多的线程需要更多的内存空间
·线程会给程序带来更多的bug,因此要小心使用
·线程的中止需要考虑其对程序运行的影响
·通常块模型数据是在多个线程间共享的,需要一个合适的锁系统替换掉数据共享