C#多线程、跨线程与线程安全的示例详解

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)
        {
            //开始异步执行
            w.BeginInvoke(10, new AsyncCallback(method), null);
            w.BeginInvoke(20, new AsyncCallback(method), null);
            Console.Read();
        }

_________________________________
/// <summary>
        /// 静态方法不需要实例化
        /// </summary>
        /// <param name="d"></param>
        public static void perimeter(object d)
        {
            Console.WriteLine(Math.PI * (double)d);
            Thread.Sleep(1000);
        }
        static void Main(string[] args)
        {
            int i = 1;
            WaitCallback wcb = new WaitCallback(perimeter);
            while (i < 15)
            {
                //将任务排入队列以便执行,您的回调方法将在某个线程池线程可用时执行
                ThreadPool.QueueUserWorkItem(wcb, (double)i);
                ++i;
            }
            Console.Read();
        }

总结

优点:
·使用线程可以把占据长时间的程序中的任务放到后台去处理
·用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
·程序的运行速度可能加快
·在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。

缺点:
·如果有大量的线程,会影响性能,因为操作系统需要在他们之间切换;
·更多的线程需要更多的内存空间
·线程会给程序带来更多的bug,因此要小心使用
·线程的中止需要考虑其对程序运行的影响
·通常块模型数据是在多个线程间共享的,需要一个合适的锁系统替换掉数据共享

时间: 2024-11-08 19:02:34

C#多线程、跨线程与线程安全的示例详解的相关文章

oracle跨库查询dblink的用法实例详解_oracle

本文实例讲述了oracle跨库查询dblink的用法.分享给大家供大家参考,具体如下: 1.创建之前的工作 在创建dblink之前,首先要查看用户是否有相应的权限.针对特定的用户,使用 sqlplus user/pwd登录后,执行如下语句: 复制代码 代码如下: select * from user_sys_privs t where t.privilege like upper('%link%'); 在sys用户下,显示结果为: SYS CREATE DATABASE LINK NO SYS

python线程、进程和协程详解_python

引言 解释器环境:python3.5.1 我们都知道python网络编程的两大必学模块socket和socketserver,其中的socketserver是一个支持IO多路复用和多线程.多进程的模块.一般我们在socketserver服务端代码中都会写这么一句: server = socketserver.ThreadingTCPServer(settings.IP_PORT, MyServer) ThreadingTCPServer这个类是一个支持多线程和TCP协议的socketserver

线程池的原理与实现详解_C 语言

一. 线程池的简介通常我们使用多线程的方式是,需要时创建一个新的线程,在这个线程里执行特定的任务,然后在任务完成后退出.这在一般的应用里已经能够满足我们应用的需求,毕竟我们并不是什么时候都需要创建大量的线程,并在它们执行一个简单的任务后销毁. 但是在一些web.email.database等应用里,比如彩铃,我们的应用在任何时候都要准备应对数目巨大的连接请求,同时,这些请求所要完成的任务却又可能非常的简单,即只占用很少的处理时间.这时,我们的应用有可能处于不停的创建线程并销毁线程的状态.虽说比起

C#中实现线程同步lock关键字的用法详解_C#教程

1. lock关键字保证一个代码块在执行的过程中不会受到其他线程的干扰,这是通过在该代码块的运行过程中对特定的对象加互斥锁来实现的. 2. lock关键字的参数必须是引用类型的对象.lock对基本数据类型如int,long等无效,因为它所作用的类型必须是对象.如果传入long类型数据,势必被转换为Int64结构类型,则加锁的是全新的对象引用.如果需要对它们进行互斥访问限制,可以使用System.Threading.Interlocked类提供的方法,这个类是提供原子操作的. 3. lock(th

python多线程编程方式分析示例详解_python

在Python多线程中如何创建一个线程对象如果你要创建一个线程对象,很简单,只要你的类继承threading.Thread,然后在__init__里首先调用threading.Thread的__init__方法即可 复制代码 代码如下: import threading  class mythread(threading.Thread):  def __init__(self, threadname):  threading.Thread.__init__(self, name = thread

Android多线程断点下载完整示例详解

MainActivity如下: package cc.activity; import java.io.File; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.

Android多线程下载示例详解

一.概述 说到Android中的文件下载,Android API中明确要求将耗时的操作放到一个子线程中执行,文件的下载无疑是需要耗费时间的,所以要将文件的下载放到子线程中执行.下面,我们一起来实现一个Android中利用多线程下载文件的小例子. 二.服务端准备 在这个小例子中我以下载有道词典为例,在网上下载有道词典的安装包,在eclipse中新建项目web,将下载的有道词典安装包放置在WebContent目录下,并将项目发布到Tomcat中,具体如下图所示 三.Android实现 1.布局 界面

Android多线程断点续传下载示例详解

一.概述 在上一篇博文<Android多线程下载示例>中,我们讲解了如何实现Android的多线程下载功能,通过将整个文件分成多个数据块,开启多个线程,让每个线程分别下载一个相应的数据块来实现多线程下载的功能.多线程下载中,可以将下载这个耗时的操作放在子线程中执行,即不阻塞主线程,又符合Android开发的设计规范. 但是当下载的过程当中突然出现手机卡死,或者网络中断,手机电量不足关机的现象,这时,当手机可以正常使用后,如果重新下载文件,似乎不太符合大多数用户的心理期望,那如何实现当手机可以正

java多线程总结一:线程的两种创建方式及优劣比较

http://blog.csdn.net/touch_2011/article/details/6891026 1.通过实现Runnable接口线程创建 (1).定义一个类实现Runnable接口,重写接口中的run()方法.在run()方法中加入具体的任务代码或处理逻辑. (2).创建Runnable接口实现类的对象. (3).创建一个Thread类的对象,需要封装前面Runnable接口实现类的对象.(接口可以实现多继承) (4).调用Thread对象的start()方法,启动线程 示例代码