zoukankan      html  css  js  c++  java
  • C# 进程 与 线程

    C#多线程和线程池
    1.0、线程的和进程的关系以及优缺点
    windows系统是一个多线程的操作系统。一个程序至少有一个进程,一个进程至少有一个线程。进程是线程的容器,一个C#客户端程序开始于一个单独的线程,CLR(公共语言运行库)为该进程创建了一个线程,该线程称为主线程。例如当我们创建一个C#控制台程序,程序的入口是Main()函数,Main()函数是始于一个主线程的。它的功能主要 是产生新的线程和执行程序。C#是一门支持多线程的编程语言,通过Thread类创建子线程。
    引入命名空间 using System.Threading。

    多线程的优点:

    1. 多线程可以提高CPU的利用率,因为当一个线程处于等待状态的时候,CPU会去执行另外的线程
    2. 提高了CPU的利用率,就可以直接提高程序的整体执行速度


    多线程的缺点:

    1. 线程开的越多,内存占用越大
    2. 协调和管理代码的难度加大,需要CPU时间跟踪线程
    3. 线程之间对资源的共享可能会产生可不遇知的问题

    1.1、前台线程和后台线程
    C#中的线程分为前台线程和后台线程,线程创建时不做设置默认是前台线程。即线程属性IsBackground=false。
    Thread.IsBackground = false;

    1.2、区别以及如何使用:
    这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。一般后台线程用于处理时间较短的任务,如在一个Web服务器中可以利用后台线程来处理客户端发过来的请求信息。而前台线程一般用于处理需要长时间等待的任务,如在Web服务器中的监听客户端请求的程序。

    1.3、多线程的创建
    首先使用new Thread()创建出新的线程,然后调用Start方法使得线程进入就绪状态,得到系统资源后就执行,在执行过程中可能有等待、休眠、死亡和阻塞四种状态。正常执行结束时间片后返回到就绪状态。如果调用Suspend方法会进入等待状态,调用Sleep或者遇到进程同步使用的锁机制而休眠等待。具体过程如下图所示:

    System.Threading
    System.Threading.Timer
    System.Threading.Tasks

    Thread th = new Thread(delegate ()
    {
      Response.Write("线程执行");
    });
    th.IsBackground = true;
    th.Start();

    或者

    Thread th = new Thread(() =>
    {
        Response.Write("线程执行");
    });

    th.IsBackground = true;
    th.Start();


    Task<string> task = Task.Factory.StartNew<string>(() =>
    {
        return "返回结果";
    });
    string result = task.Result;
    或者

    Task.Factory.StartNew(() =>
    {
        //用来计算运行时间
        System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
        double ms = sw.ElapsedMilliseconds / 1000;
    });


    protected void Button1_Click(object sender, EventArgs e)
    {
    ThreadPool.QueueUserWorkItem(new WaitCallback(WorkItem), null);
    }
    private void WorkItem(object obj)
    {
    TextBox1.Text = "执行完成";
    }


    子线程与主线程之间通信

    private SynchronizationContext synContext;
    public MainWindow()
    {
        InitializeComponent();
        //在这里记录主线程的上下文
        synContext = SynchronizationContext.Current;
        Task.Factory.StartNew(() =>
        {
            //用来计算运行时间
            System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
            double ms = sw.ElapsedMilliseconds / 1000;
            //通知主线程
            synContext.Post(new SendOrPostCallback(OnConnected), null);
        });
    }
    //由于是主线程的同步对象Post调用,这个是在主线程中执行的
    private void OnConnected(object state)
    {
        //这里就回到了主线程里面了
        //做一些事情
    }


    两个子线程的相互通信

    EventWaitHandle handleA = new AutoResetEvent(false);
    EventWaitHandle handleB = new AutoResetEvent(false);
    public 两个子线程的相互通信()
    {
        InitializeComponent();
        ThreadPool.QueueUserWorkItem(ar =>
        {
            //发出信号并等待另一个
            EventWaitHandle.SignalAndWait(handleB, handleA);
        });

        ThreadPool.QueueUserWorkItem(ar =>
        {
            handleB.WaitOne();
            EventWaitHandle.SignalAndWait(handleA, handleB);
            handleA.Set();
        });
    }

  • 相关阅读:
    MSB4064 错误
    javascript 通过模块模式实现代码访问控制
    vs 2012 更新update4 后出现问题
    html 转 PDF wkhtmltopdf image 不能显示的问题
    Html方式导出word 页头和页脚设置
    使用JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串的长度超过了为 maxJsonLength属性
    经验1-打印web
    DataGridView 多线程更新 数据 解决卡顿问题
    Copy List with Random Pointer [LeetCode]
    Validate Binary Search Tree [LeetCode]
  • 原文地址:https://www.cnblogs.com/sntetwt/p/11126329.html
Copyright © 2011-2022 走看看