C#编程总结(四)多线程应用

C#编程总结(四)多线程应用

多线程应用很广泛,简单总结了一下:

1)不阻断主线程,实现即时响应,由后台线程完成特定操作
2)多个线程,完成同类任务,提高并发性能
3)一个任务有多个独立的步骤,多个线程并发执行各子任务,提高任务处理效率

下面我们通过几个小例子做简单介绍。

1、进度条

分析:页面动态刷新,主页面正常可操作。我们通过后台线程来实现进度条。

首先,创建Winform页面,然后拖入进度条控件,将页面的代码改为以下代码即可。

这里只是个简单的例子,其实我们可以做的更好,将进度条封装为一个自定义控件,设计为一个通用好看的进度条。这里只讲技术和方向,大家可以自己研究研究。

相关代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ProgressBarSample
{
    //定义委托,异步调用
    delegate void ShowProgressDelegate(int totalStep, int currentStep);
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            ParameterizedThreadStart start = new ParameterizedThreadStart(SetProgress);
            Thread progressThread = new Thread(start);
            progressThread.IsBackground = true;//标记为后台进程,在窗口退出时,正常退出
            progressThread.Start();
        }
        /// <summary>
        /// 设置当前进度
        /// </summary>
        /// <param name="state"></param>
        void SetProgress(object state)
        {
            for (int i = 1; i <= 100; i++)
            {
                Thread.Sleep(200);
                object[] objs = new object[] { 100, i };
                //异步调用
                this.Invoke(new ShowProgressDelegate(ShowProgress), objs);
            }
        }
        /// <summary>
        /// 刷新进度条
        /// </summary>
        /// <param name="totalStep"></param>
        /// <param name="currentStep"></param>
        void ShowProgress(int totalStep, int currentStep)
        {
            this.progressBar1.Maximum = totalStep;
            this.progressBar1.Value = currentStep;

            this.lbCurrent.Text = this.progressBar1.Value * 100 / progressBar1.Maximum + "%";
        }
    }
}

2、网络扒虫

经常遇到这样的场景,通过扒虫程序,去互联网获取所需资源。其实搜索引擎的一个重要组成部分就是扒虫。但是,往往扒虫程序比较费时,这时就需要多线程帮忙。

这里写一个简单的扒虫程序,说明下原理。

案例:通过网络连接,获取网络相关信息。

扒虫对象:

using System;
using System.Net;

namespace Reptile
{
    public class NetReptile
    {
        /// <summary>
        ///
        /// </summary>
        public string Url { get; set; }
        /// <summary>
        ///
        /// </summary>
        /// <param name="url"></param>
        public NetReptile(string url)
        {
            this.Url = url;
        }

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public string GetContent()
        {
            WebClient client = new WebClient();
            return client.DownloadString(new Uri(this.Url));
        }
    }
}

抓到内容后,需要解析,提取我们需要的内容,这里以抓取网页的标题为例。解析器代码:

using System;
using System.Text;
using System.Text.RegularExpressions;

namespace Reptile
{
    /// <summary>
    /// HTML解析器
    /// </summary>
    public class HtmlAnalyzer
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public HtmlAnalyzer()
        { }
        /// <summary>
        /// 获取标题
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public string GetTitle(string html)
        {
            Regex regext = new Regex("(?<=<title>).*?(?=</title>)");
            Match m = regext.Match(html);
            if (m != null)
            {
                return m.ToString();
            }

            return null;
        }

    }
}

使用多线程创建扒虫,抓取数据:

   /// <summary>
        /// 多线程处理
        /// </summary>
        private void MultiThread()
        {
            string urls = tbUrl.Text;
            string[] separater = { "\r\n" };
            string[] urlList = urls.Split(separater, StringSplitOptions.RemoveEmptyEntries);
            int i = 1;

            foreach (var url in urlList)
            {
                Thread thread = new Thread(new ParameterizedThreadStart(Snap));
                thread.Name = "Thread" + i.ToString();
                thread.Start(url);
                i++;
            }

            //RefreshData();
        }
        /// <summary>
        /// 抓取数据
        /// </summary>
        /// <param name="state"></param>
        private void Snap(object state)
        {
            string url = state as string;
            NetReptile reptile = new NetReptile(url);
            string html = reptile.GetContent();

            if (!string.IsNullOrEmpty(html))
            {
                HtmlAnalyzer analyzer = new HtmlAnalyzer();
                string title = analyzer.GetTitle(html);
                Thread.Sleep(2000);
                this.Invoke(new AddItemDelegate(this.AddItem),title);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="item"></param>
        private void AddItem(string item)
        {
            this.listData.Items.Add(item);
        }

全部源码:http://files.cnblogs.com/yank/Reptile.rar

其他:

多线程应用还有很多,比如:文件上传和下载、异步加载、Web请求、压力测试、流水线技术等等。后续我们还会将一些典型案例更新在这里。

时间: 2024-12-29 23:44:22

C#编程总结(四)多线程应用的相关文章

iOS多线程编程(四)------ GCD(Grand Central Dispatch)

一.简介 是基于C语言开发的一套多线程开发机制,也是目前苹果官方推荐的多线程开发方法,用起来也最简单,只是它基于C语言开发,并不像NSOperation是面向对象的开发,而是完全面向过程的.如果使用GCD,完全由系统管理线程,我们不需要编写线程代码.只需定义想要执行的任务,然后添加到适当的调度队列(dispatch_queue).GCD会负责创建线程和调度你的任务,系统会直接提供线程管理. 二.任务和队列 GCD中有两个核心概念 (1)任务:执行什么操作 (2)队列:用来存放任务 GCD的使用就

[转帖]编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程

编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程原创luoweifu 发布于2015-06-22 20:05:28 阅读数 75442 收藏展开 原文:http://blog.csdn.net/luoweifu/article/details/46595285 作者:luoweifu 转载请标名出处 其实我还有一个不太清楚的地方 一个进程 应该只能存在于一个核上面吧 一个进程的多个线程 应该不能跨越CPU的核心进行工作吧? 不太明白. 什么是线程什么是线程?线程与进程与有什么关系

关于shell脚本基础编程第四篇

shell脚本基础编程第四篇本章主要内容:函数 函数 function:             function 名称 { 命令 ; } 或 name () { 命令 ; }           定义 shell 函数.               创建一个以 NAME 为名的 shell 函数.当作为一个简单的命令启用时,           NAME 函数执行调用 shell 的上下文中的 COMMANDs 命令.当 NAME           被启用时,参数作为 $1...$n 被传递

编程思想之多线程与多进程(2)——线程优先级与线程安全

原文:http://blog.csdn.net/luoweifu/article/details/46701167 作者:luoweifu 转载请标名出处 <编程思想之多线程与多进程(1)--以操作系统的角度述说线程与进程>一文详细讲述了线程.进程的关系及在操作系统中的表现,这是多线程学习必须了解的基础.本文将接着讲一下线程优先级和线程安全. 线程优先级 现在主流操作系统(如Windows.Linux.Mac OS X)的任务调度除了具有前面提到的时间片轮转的特点外,还有优先级调度(Prior

Linux统系统开发11 Socket API编程2 多进程 多线程 高并发处理

[本文谢绝转载原文来自http://990487026.blog.51cto.com] <纲要> Linux统系统开发11 Socket API编程2 多进程 多线程 高并发处理 UDP服务器 客户端最小模型,处理字符转大写 TCP 多进程并发服务器模型,为每个客户端开启一个进程: TCP 多线程服务器模型,使用wrap函数封装 作业: ---------------------------------------------------- UDP服务器 客户端最小模型,处理字符转大写 [em

编程思想之多线程与多进程(4)——C++中的多线程

<编程思想之多线程与多进程(1)--以操作系统的角度述说线程与进程>一文详细讲述了线程.进程的关系及在操作系统中的表现,<编程思想之多线程与多进程(2)--线程优先级与线程安全>一文讲了线程安全(各种同步锁)和优先级,这是多线程学习必须了解的基础.本文将接着讲一下C++中多线程程序的开发.这里主要讲Windows平台线程的用法,创建线程要调用windows API的CreateThread方法. 创建线程 在Windows平台,Windows API提供了对多线程的支持.前面进程和

编程思想之多线程与多进程(2)——Java中的多线程

原文:http://blog.csdn.net/luoweifu/article/details/46673975 作者:luoweifu 转载请标名出处 <编程思想之多线程与多进程(1)--以操作系统的角度述说线程与进程>一文详细讲述了线程.进程的关系及在操作系统中的表现,这是多线程学习必须了解的基础.本文将接着讲一下Java中多线程程序的开发 单线程 任何程序至少有一个线程,即使你没有主动地创建线程,程序从一开始执行就有一个默认的线程,被称为主线程,只有一个线程的程序称为单线程程序.如下面

生活编程(四)——学校图书馆简化

    每次在信号不好的图书馆打开图书检索的主页就是漫长的等待. 其实,所以便萌生了一个想法.我只要简单一个form就可以了.然后嵌入到移动设备就可以了.图书馆后台的查询处理是这样的 http://library.com/searchresult.aspx?anywords=%b7%bd%b7%a8&dt=ALL&cl=ALL&dp=20&sf=M_PUB_YEAR&ob=DESC&sm=table&dept=ALL anywords就是关键,之前以

Apache Kafka系列(四) 多线程Consumer方案

Apache Kafka系列(一) 起步 Apache Kafka系列(二) 命令行工具(CLI) Apache Kafka系列(三) Java API使用 Apache Kafka系列(四) 多线程Consumer方案 本文的图片是通过PPT截图出的,读者如果修改意见请联系我 一.Consumer为何需要实现多线程 假设我们正在开发一个消息通知模块,该模块允许用户订阅其他用户发送的通知/消息.该消息通知模块采用Apache Kafka,那么整个架构应该是消息的发布者通过Producer调用AP

面向对象编程(十四)——面向对象三大特性之多态②

面向对象最核心的机制——动态绑定,也叫多态. 通过下面的例子理解动态绑定,即多态 1 package javastudy.summary; 2 3 class Animal { 4 /** 5 * 声明一个私有的成员变量name. 6 */ 7 private String name; 8 9 /** 10 * 在Animal类自定义的构造方法 11 * @param name 12 */ 13 Animal(String name) { 14 this.name = name; 15 } 16