xml地图|网站地图|网站标签 [设为首页] [加入收藏]
事件剖析,txt设置编码格式
分类:编程

在excel中设置保存之后的编码格式,需要获取到Microsoft.Office.Interop.Excel.Workbook然后设置其中的webOpetions的编码格式就可以了。

本节对事件进行总结。

CLR线程池并不会在CLR初始化时立即建立线程,而是在应用程序要创建线程来运行任务时,线程池才初始化一个线程。
线程池初始化时是没有线程的,线程池里的线程的初始化与其他线程一样,但是在完成任务以后,该线程不会自行销毁,而是以挂起的状态返回到线程池。直到应用程序再次向线程池发出请求时,线程池里挂起的线程就会再度激活执行任务。
这样既节省了建立线程所造成的性能损耗,也可以让多个任务反复重用同一线程,从而在应用程序生存期内节约大量开销。

workbook.WebOptions.Encoding = Microsoft.Office.Core.MsoEncoding.msoEncodingUTF8;// 设置utf编码格式

二、事件:

通过CLR线程池所建立的线程总是默认为后台线程,优先级数为ThreadPriority.Normal。

在word中设置编码格式,可以直接在获取到的Microsoft.Office.Interop.Word.Document中设置保存格式。

1、概念:Event:A member that enables an object or class to provide notifications;官方的解释是这样,就是说在C#中,事件是使

CLR线程池分为工作者线程(workerThreads)I/O线程(completionPortThreads)两种:

document.SaveEncoding = MsoEncoding.msoEncodingUTF8;// 设置保存的编码格式为utf8

对象或者类具备通知能力的成员。比如说手机收到短信提醒我去开会,那么手机就充当了一个具备通知能力的成员。说白了,事件

  • 工作者线程是主要用作管理CLR内部对象的运作,通常用于计算密集的任务。
  • I/O(Input/Output)线程主要用于与外部系统交互信息,如输入输出,CPU仅需在任务开始的时候,将任务的参数传递给设备,然后启动硬件设备即可。等任务完成的时候,CPU收到一个通知,一般来说是一个硬件的中断信号,此时CPU继续后继的处理工作。在处理过程中,CPU是不必完全参与处理过程的,如果正在运行的线程不交出CPU的控制权,那么线程也只能处于等待状态,即使操作系统将当前的CPU调度给其他线程,此时线程所占用的空间还是被占用,而并没有CPU处理这个线程,可能出现线程资源浪费的问题。如果这是一个网络服务程序,每一个网络连接都使用一个线程管理,可能出现大量线程都在等待网络通信,随着网络连接的不断增加,处于等待状态的线程将会很消耗尽所有的内存资源。可以考虑使用线程池解决这个问题。

  

的作用就是对象和类之间的信息传递的桥梁。

  线程池的最大值一般默认为1000、2000。当大于此数目的请求时,将保持排队状态,直到线程池里有线程可用。

2、原理:源于发生-响应模型:

  使用CLR线程池的工作者线程一般有两种方式:

事件源(event source) + 事件本身(event) => 事件的订阅者(event subscriber) + 事件处理器(event handler)           

  • 通过ThreadPool.QueueUserWorkItem()方法;
  • 通过委托;

(另外还有事件的订阅者和事件源之间的订阅关系subscribe relationship)

  要注意,不论是通过ThreadPool.QueueUserWorkItem()还是委托,调用的都是线程池里的线程。

还是以手机收到短信提醒我去开会为例,事件源:手机吗,事件:收到短信,事件的订阅者:我,事件处理器:去开会,订阅关系:我订阅手机

通过以下两个方法可以读取和设置CLR线程池中工作者线程与I/O线程的最大线程数。

3、事件的声明:分为详细声明和简略声明:

  1. ThreadPool.GetMax(out in workerThreads,out int completionPortThreads);
  2. ThreadPool.SetMax(int workerThreads,int completionPortThreads);

(1)详细声明:

public delegate void MyDelegateEventHandler();
    public class Event
    {
        private MyDelegateEventHandler myDelegateEventHandler;
        public event MyDelegateEventHandler MyDelegate
        {
            add
            {
                this.myDelegateEventHandler += value;
            }
            remove
            {
                this.myDelegateEventHandler -= value;
            }
        }
    }

  若想测试线程池中有多少线程正在投入使用,可以通过ThreadPool.GetAvailableThreads(out in workThreads,out int conoletionPortThreads)方法。

(2)简略说明:

public delegate void MyDelegateEventHandler();
    public class Event
    {
         public event MyDelegateEventHandler myDelegate;
    }
方法 说明
GetAvailableThreads 剩余空闲线程数
GetMaxThreads 最多可用线程数,所有大于此数目的请求将保持排队状态,直到线程池线程变为可用
GetMinThreads 检索线程池在新请求预测中维护的空闲线程数
QueueUserWorkItem 启动线程池里得一个线程(队列的方式,如线程池暂时没空闲线程,则进入队列排队)
SetMaxThreads 设置线程池中的最大线程数
SetMinThreads 设置线程池最少需要保留的线程数

可以看到,在完整声明中首先添加了一个委托类型的字段,然后暴漏了添加和移除事件处理器的功能,但是我们经常用的是简略声明,因为代码更加简洁,

我们可以使用线程池来解决上面的大部分问题,跟使用单个线程相比,使用线程池有如下优点:

可以看出事件对外界隐藏了大部分功能,它的本质就是对其中委托字段的一个封装(encapsulation),防止外界偷用滥用委托字段。

1、缩短应用程序的响应时间。因为在线程池中有线程的线程处于等待分配任务状态(只要没有超过线程池的最大上限),无需创建线程。

那么问题来了:第一个问题:有了委托为什么还会有事件呢,事件内部不就是委托吗,原因是为了防止public型的委托字段在外面被滥用,比如委托可以用invoke调用,

2、不必管理和维护生存周期短暂的线程,不用在创建时为其分配资源,在其执行完任务之后释放资源。

但是事件只能在+=或-=的左侧,这样就增加了整个程序的安全性。

3、线程池会根据当前系统特点对池内的线程进行优化处理。

第二个问题:那委托和事件的关系什么样的呢?我们说事件是基于委托的。一方面,事件需要委托来做一个约束,这个约束规定了事件源发送什么要求给事件的订阅者,

总之使用线程池的作用就是减少创建和销毁线程的系统开销。在.NET中有一个线程的类ThreadPool,它提供了线程池的管理。

事件订阅者的事件处理器必须和这个约束相对应才可以订阅这个事件,另一方面,事件订阅者收到事件以后做出事件处理器,而这个事件处理器必须通过委托才可以做到。

ThreadPool是一个静态类,它没有构造函数,对外提供的函数也全部是静态的。其中有一个QueueUserWorkItem方法,它有两种重载形式,如下:

4、简单实例:

public static bool QueueUserWorkItem(WaitCallback callBack):将方法排入队列以便执行。此方法在有线程池线程变得可用时执行。

Example:做一个窗口,有文本框和按钮,点击按钮文本框显示时间,不用WindowsForms

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ConsoleApp14
{
    class Program
    {
        public static TextBox textBox;
        public static Button button;
        static void Main(string[] args)
        {
            Form form = new Form();
            TextBox textBox = new TextBox();
            Button button = new Button();
            form.Controls.Add(textBox);
            form.Controls.Add(button);
            textBox.Width = 400;
            button.Top = 100;
            button.Click += Button_Click;
            form.ShowDialog();
        }

        private static void Button_Click(object sender, EventArgs e)
        {
            textBox.Text = DateTime.Now.ToString();
        }
    }
}

图片 1

 

public static bool QueueUserWorkItem(WaitCallback callBack,Object state):将方法排入队列以便执行,并指定包含该方法所用数据的对象。此方法在有线程池线程变得可用时执行。

这里举的事例就是windowsforms内部的代码,我们说事件本身是不会发生的是由事件源内部的逻辑所触发,在本例中,并不是人按了按钮然后按钮触发了事件,

QueueUserWorkItem方法中使用的的WaitCallback参数表示一个delegate,它的声明如下:

本文由澳门新葡亰手机版发布于编程,转载请注明出处:事件剖析,txt设置编码格式

上一篇:线程基础,log4net使用方法 下一篇:又叫抗变,希尔排序
猜你喜欢
热门排行
精彩图文