必赢网上注册-亚洲必赢官方登录

使用线程池,记录日志

日期:2019-11-28编辑作者:必赢网上注册

         由于UDP探讨并没有必要进行规定的连续几日,程序中能够无需思谋连接和有些十分的捕获职业。在多少对数据安全性须求不是非常高的情形下使用UDP左券。

  signalLX570内部有两类对象:

1.1 简介

在本章中,首要介绍线程池(ThreadPool)的使用;在C#中它叫System.Threading.ThreadPool,在使用线程池此前率先大家得精晓叁个标题,那就是怎么要使用线程池。其根本原因是制造二个线程的代价是高昂的,创设八个线程会消耗非常多的系统能源。

那就是说线程池是什么减轻那个主题材料的吧?线程池在开班时会自动创设一定量的线程供程序调用,使用时,开垦人士并不直接分配线程,而是将索要做的做事归入线程池专门的职业行列中,由线程池分配本来就有的线程举办管理,等管理实现后线程不是被销毁,而是再一次回来线程池中,那样节约了创建线程的开采。

不过在使用线程池时,须求潜心以下几点,这将特别重要。

  • 线程池不切合管理长日子运作的学业,也许管理必要与别的线程同步的课业。
  • 防止将线程池中的工作线程分配给I/O首先的职责,这种职务应该利用TPL模型。
  • 如非必得,不要手动设置线程池的最小线程数和最大线程数,CL福特Explorer会自动的进行线程池的恢弘和裁减,手动干预往往让质量更差。

时间会记录下一切。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
 </configSections>

  <log4net>
    <logger name="sendEmailrError">
      <level value="ALL"/>
      <!--ALL DEBUG INFO WARN ERROR FATAL OFF-->
      <appender-ref ref="RollingLogFileAppender"/> 
    </logger>

    <!--<logger name="ugmrob2bLoggerInfo">
      <level value="ALL"/>
      --><!--ALL DEBUG INFO WARN ERROR FATAL OFF--><!--
      <appender-ref ref="LoggerInfo"/>
    </logger>-->

    <appender name="LoggerInfo" type="log4net.Appender.RollingFileAppender"> 
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <!--存放日志的路径-->
      <param name="File" value="E:/Log/LogInfo/"/>
      <!--日志文件中追加-->
      <param name="AppendToFile" value="true"/>
      <!--日期文件是否固定不变-->
      <param name="StaticLogFileName" value="false"/>
      <!--最多保存多少天的记录-->
      <param name="MaxSizeRollBackups" value="100"/>
      <param name="MaximumFileSize" value="5MB"/>
      <!--日志名称-->
      <param name="DatePattern" value="yyyy-MM-dd".log""/>
      <!--日志根据日期滚动-->
      <param name="RollingStyle" value="Date"/>

      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%n异常时间: %d%n记录器: %c%n异常信息: %m%n异常位置:[%t] %-5p [%l]%n"/>
      </layout>
    </appender>

    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <!--存放日志的路径-->
      <param name="File" value="E:/Log/LogError/"/>
      <!--日志文件中追加-->
      <param name="AppendToFile" value="true"/>
      <!--日期文件是否固定不变-->
      <param name="StaticLogFileName" value="false"/>
      <!--最多保存多少天的记录-->
      <param name="MaxSizeRollBackups" value="100"/>
      <param name="MaximumFileSize" value="5MB"/>
      <!--日志名称-->
      <param name="DatePattern" value="yyyy-MM-dd".log""/>
      <!--日志根据日期滚动-->
      <param name="RollingStyle" value="Date"/>
      <layout type="log4net.Layout.PatternLayout">
        <!--<param name="ConversionPattern" value="%n异常时间: %d%n记录器: %c%n异常信息: %m%n异常位置:[%t] %-5p [%l]%n"/>-->
        <conversionPattern value="%n记录时间:%date 线程ID:[%thread] 日志级别:%-5level  %n错误描述:%message%newline" />

      </layout>
      <!--<filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="DEBUG"/>
        <param name="LevelMax" value="FATAL"/>
      </filter>-->
    </appender>

  </log4net>

</configuration>

(2)TcpClient类:依附Socket类创设,用于在联名阻止格局下通过网络来连接,发送,选用数据。

 

1.8 使用BackgroundWorker组件

本节主要介绍BackgroundWorker组件的选取,该零零件实际上被用来Windows窗体应用程序(Windows Forms Application,简称WPF卡塔尔中,通过它达成的代码能够一贯与UI调整器交互作用,尤其自认和好用。

示范代码如下所示,使用BackgroundWorker来落到实处对数据开展总计,并且让其接济报告专门的学问进度,帮助打消职务。

static void Main(string[] args)
{
    var bw = new BackgroundWorker();
    // 设置可报告进度更新
    bw.WorkerReportsProgress = true;
    // 设置支持取消操作
    bw.WorkerSupportsCancellation = true;

    // 需要做的工作
    bw.DoWork += Worker_DoWork;
    // 工作处理进度
    bw.ProgressChanged += Worker_ProgressChanged;
    // 工作完成后处理函数
    bw.RunWorkerCompleted += Worker_Completed;

    bw.RunWorkerAsync();

    WriteLine("按下 `C` 键 取消工作");
    do
    {
        if (ReadKey(true).KeyChar == 'C')
        {
            bw.CancelAsync();
        }

    }
    while (bw.IsBusy);
}

static void Worker_DoWork(object sender, DoWorkEventArgs e)
{
    WriteLine($"DoWork 线程池 线程 id: {CurrentThread.ManagedThreadId}");
    var bw = (BackgroundWorker)sender;
    for (int i = 1; i <= 100; i++)
    {
        if (bw.CancellationPending)
        {
            e.Cancel = true;
            return;
        }
        if (i % 10 == 0)
        {
            bw.ReportProgress(i);
        }

        Sleep(TimeSpan.FromSeconds(0.1));
    }

    e.Result = 42;
}

static void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    WriteLine($"已完成{e.ProgressPercentage}%. " +
              $"处理线程 id: {CurrentThread.ManagedThreadId}");
}

static void Worker_Completed(object sender, RunWorkerCompletedEventArgs e)
{
    WriteLine($"完成线程池线程 id: {CurrentThread.ManagedThreadId}");
    if (e.Error != null)
    {
        WriteLine($"异常 {e.Error.Message} 发生.");
    }
    else if (e.Cancelled)
    {
        WriteLine($"操作已被取消.");
    }
    else
    {
        WriteLine($"答案是 : {e.Result}");
    }
}

运转结果如下所示。

图片 1

在本节中,使用了C#中的另外一个语法,叫事件(event)。当然这里的事件差异于此前在线程同步章节中涉及的风浪,这里是观看者设计情势的体现,包括事件源、订阅者和事件管理程序。因而,除了异步APM格局意外,还会有依照事件的异步情势(伊芙nt-based Asynchronous Pattern,简称 EAP卡塔尔(英语:State of Qatar)

图片 2

    这段时间写了个定时邮件推送的劳务,当使用lognet4记录日志时,发掘日志并不曾记录。后来晓得windows 服务经常暗许是在C:使用线程池,记录日志。WindowsSystem 或是C:WindowsSystem32,而作者辈友好的服务程序平日是坐落别的的目录,这样log4net.config文件中的配置路径将无法准确分析。所以就不能够记录日志。本来作者的lognet4文书与劳务文件坐落于同一目录,后来作者就把lognet4.config文件放在了程序exe所在的目录。

互连网编制程序

docs.microsoft t

目录

class Class2: Iinterface1, Iinterface2, Iinterface3 {}
log4net.ILog log = log4net.LogManager.GetLogger("sendEmailrError");
log.Error("错误信息");
1 TcpClient tcpClient = new TcpClient();             //创建TcpClient对象实例
2 tcpClient.Connect("www.baidu.com",4088);         //尝试与远程主机相连
3 NetworkStream stream=tcpClient.GetStream();      //获取网络传输流

Install-Package microsoft.owin.cors 


Partial关键词定义的类能够在几个地方被定义,最后编写翻译的时候会被用作五个类来拍卖。

 2. 随着在Main入口函数剖析lognet4.config文本。

        首要提供制作Sockets互连网应用程序的连带类,当中Socket类,TcpClient类、TcpListener类和UdpClient类较为常用。在.NET框架下支付时,直接利用System.Net.Sockets名称空间中的Socket类编制程序较为复杂,而应用层的类TcpClient、TcpListener 和 UdpClient为 Socket 通讯提供了更简便、对顾客更温馨的接口。它们和Socket类之间的这种档案的次序关系如图

](:

我水平有限,要是不当接待各位商酌指正!

partial class Class2: Iinterface1, Iinterface2 {}
partial class Class2: Iinterface3 {}
partial class Class2: Iinterface2 {}
  static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        static void Main()
        {
            string assemblyFilePath = Assembly.GetExecutingAssembly().Location;
            string assemblyDirPath = Path.GetDirectoryName(assemblyFilePath);
            string configFilePath = assemblyDirPath + "\log4net.config";
            XmlConfigurator.ConfigureAndWatch(new FileInfo(configFilePath));

            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new SendEmailService() 
            };
            ServiceBase.Run(ServicesToRun);
        }
    }
1 TcpClient tcpClient = new TcpClient();//创建TcpClient对象实例
2 tcpClient.Connect("www.baidu.com",8080);//建立连接

1.预约义的品种“Microsoft.C夏普.RuntimeBinder.Binder”未定义或未导入:[

1.5 实现几个撤回选项

在事情发生前的小说中有关系,倘诺急需甘休三个线程的实施,那么能够运用Abort()艺术,然而有那个的原因并不引入应用Abort()方法。

此处推荐的点子是应用同盟式打消(cooperative cancellation卡塔尔(قطر‎,那是风流浪漫种有限扶植的技能来安全裁撤不再须求的天职。其利害攸关选择CancellationTokenSourceCancellationToken八个类,具体用法见下边演示代码。

以下延时代码重假设得以完结了接纳CancellationTokenCancellationTokenSource来实现任务的吊销。不过职责撤消后能够展开三种操作,分别是:直接回到、抛出ThrowIfCancellationRequesed可怜和实行回调。详细请看代码。

static void Main(string[] args)
{
    // 使用CancellationToken来取消任务  取消任务直接返回
    using (var cts = new CancellationTokenSource())
    {
        CancellationToken token = cts.Token;
        ThreadPool.QueueUserWorkItem(_ => AsyncOperation1(token));
        Sleep(TimeSpan.FromSeconds(2));
        cts.Cancel();
    }

    // 取消任务 抛出 ThrowIfCancellationRequesed 异常
    using (var cts = new CancellationTokenSource())
    {
        CancellationToken token = cts.Token;
        ThreadPool.QueueUserWorkItem(_ => AsyncOperation2(token));
        Sleep(TimeSpan.FromSeconds(2));
        cts.Cancel();
    }

    // 取消任务 并 执行取消后的回调函数
    using (var cts = new CancellationTokenSource())
    {
        CancellationToken token = cts.Token;
        token.Register(() => { WriteLine("第三个任务被取消,执行回调函数。"); });
        ThreadPool.QueueUserWorkItem(_ => AsyncOperation3(token));
        Sleep(TimeSpan.FromSeconds(2));
        cts.Cancel();
    }

    ReadLine();
}

static void AsyncOperation1(CancellationToken token)
{
    WriteLine("启动第一个任务.");
    for (int i = 0; i < 5; i++)
    {
        if (token.IsCancellationRequested)
        {
            WriteLine("第一个任务被取消.");
            return;
        }
        Sleep(TimeSpan.FromSeconds(1));
    }
    WriteLine("第一个任务运行完成.");
}

static void AsyncOperation2(CancellationToken token)
{
    try
    {
        WriteLine("启动第二个任务.");

        for (int i = 0; i < 5; i++)
        {
            token.ThrowIfCancellationRequested();
            Sleep(TimeSpan.FromSeconds(1));
        }
        WriteLine("第二个任务运行完成.");
    }
    catch (OperationCanceledException)
    {
        WriteLine("第二个任务被取消.");
    }
}

static void AsyncOperation3(CancellationToken token)
{
    WriteLine("启动第三个任务.");
    for (int i = 0; i < 5; i++)
    {
        if (token.IsCancellationRequested)
        {
            WriteLine("第三个任务被取消.");
            return;
        }
        Sleep(TimeSpan.FromSeconds(1));
    }
    WriteLine("第三个任务运行完成.");
}

运营结果如下所示,符合预期结果。

图片 3

注:Attribute2属性允许在类上翻来复去应用。

 3.  实例ILog,开首记录日志,当中sendEmailrError为lognet4.config文件中logger的name名称。

        在System.Net.Sockets命名空间下的UdpClient类,提供越来越直观的轻便使用的性质和章程,进而减少UDP编制程序的难度。使用UdpClient时,连接的顾客端要求首发送贰个音信给服务器,服务器工夫和顾客端通信。

 

1.7 使用沙漏

反应计时器是FCL提供的多个类,叫System.Threading.Timer,可要结果与创造周期性的异步操作。该类应用比较轻松。

以下的示范代码应用了停车计时器,并安装了反应计时器延时运营时间和周期时间。

static void Main(string[] args)
{
    WriteLine("按下回车键,结束定时器...");
    DateTime start = DateTime.Now;

    // 创建定时器
    _timer = new Timer(_ => TimerOperation(start), null
        , TimeSpan.FromSeconds(1)
        , TimeSpan.FromSeconds(2));
    try
    {
        Sleep(TimeSpan.FromSeconds(6));

        _timer.Change(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(4));

        ReadLine();
    }
    finally
    {
        //实现了IDispose接口  要及时释放
        _timer.Dispose();
    }
}

static Timer _timer;

static void TimerOperation(DateTime start)
{
    TimeSpan elapsed = DateTime.Now - start;
    WriteLine($"离 {start} 过去了 {elapsed.Seconds} 秒. " +
              $"定时器线程池 线程 id: {CurrentThread.ManagedThreadId}");
}

运作结果如下所示,可以看到电磁打点计时器依据所设置的周期时间循环的调用TimerOperation()方法。

图片 4

[Attribute1, Attribute2("Hello")]
partial class Class1{}

[Attribute3, Attribute2("Exit")]
partial class Class1{}

    1.  作者的lognet4.config文件配置内容如下:

        注:要创立NetworkStream必得提供连接的Socket.默许情况下关闭NetworkStream并不会关闭所提供的Socket.若是要关门Socket权限,则必得将ownsSocket布局函数参数的值钦定为true.而后的多少读取及写入均指向那几个通道来开展。不扶持对网络流的轻松访问。

 

  • 1.1 简介
  • 1.2 在线程池中调用委托
  • 1.3 向线程池中放入异步操作
  • 1.4 线程池与并行度
  • 1.5 达成二个注销选项
  • 1.6 在线程池中选拔等待事件微处理器及超时
  • 1.7 使用放大计时器
  • 1.8 使用BackgroundWorker组件
  • 参照他事他说加以考查书籍
  • 作者水平有限,假如不当迎接各位商议指正!

(1卡塔尔 三个项目标各样部分上点名的基类必得风流罗曼蒂克律。有个别部分能够不钦定基类,但万一内定,则务必意气风发律。
(2卡塔尔(قطر‎ 局地类型上的接口具备“累积”效应。

  

图片 5

示例代码下载

1.4 线程池与并行度

在本节中,首即使利用普通创立线程和使用线程池内的线程在职责量非常的大的情事下有啥界别,大家模拟了一个气象,成立了超级多莫衷一是的线程,然后分别使用普通创造线程格局和线程池方式看看有怎么着两样。

static void Main(string[] args)
{
    const int numberOfOperations = 500;
    var sw = new Stopwatch();
    sw.Start();
    UseThreads(numberOfOperations);
    sw.Stop();
    WriteLine($"使用线程执行总用时: {sw.ElapsedMilliseconds}");

    sw.Reset();
    sw.Start();
    UseThreadPool(numberOfOperations);
    sw.Stop();
    WriteLine($"使用线程池执行总用时: {sw.ElapsedMilliseconds}");

    Console.ReadLine();
}

static void UseThreads(int numberOfOperations)
{
    using (var countdown = new CountdownEvent(numberOfOperations))
    {
        WriteLine("通过创建线程调度工作");
        for (int i = 0; i < numberOfOperations; i++)
        {
            var thread = new Thread(() =>
            {
                Write($"{CurrentThread.ManagedThreadId},");
                Sleep(TimeSpan.FromSeconds(0.1));
                countdown.Signal();
            });
            thread.Start();
        }
        countdown.Wait();
        WriteLine();
    }
}

static void UseThreadPool(int numberOfOperations)
{
    using (var countdown = new CountdownEvent(numberOfOperations))
    {
        WriteLine("使用线程池开始工作");
        for (int i = 0; i < numberOfOperations; i++)
        {
            ThreadPool.QueueUserWorkItem(_ =>
            {
                Write($"{CurrentThread.ManagedThreadId},");
                Sleep(TimeSpan.FromSeconds(0.1));
                countdown.Signal();
            });
        }
        countdown.Wait();
        WriteLine();
    }
}

推行结果如下,可以预知使用原有的创造线程推行,速度相当慢。只花了2分钟,但是创造了500四个线程,而使用线程池相对来讲相当慢,花了9分钟,但是只开创了少之又少的线程,为操作系统节省了线程和内部存款和储蓄器空间,但花了越来越多的光阴。

图片 6

Partial是有的类型的意趣。允许大家将二个类、布局或接口分成多少个部分,分别实以往多少个例外的.cs文件中。C#编写翻译器在编译的时候仍会将次第部分的一些类型合并成多少个完璧归赵的类

    

  1. TCP是面向连接的服务、UDP是面向无连接服务
  2. TCP是具有差错调整的,而UDP未有贫乏可信性
  3. TCP的传输是上行下效的,UDP是冬天的
  4. UDP的实时性更加好,有简要,快捷、占用财富少的独特之处。
  5. UDP传输限制在64KB之内,Tcp风度翩翩旦创建连接,就足以按统豆蔻梢头的格式传输多量的数据。

3.有关SignalEscort连接数量难题的笔录:

1.3 向线程池中归入异步操作

本节将介绍怎么样将异步操作放入线程池中推行,并且怎么样传递参数给线程池中的线程。本节中要害运用的是ThreadPool.QueueUserWorkItem()方法,该方法可将索要周转的天职通过信托的款式传递给线程池中的线程,并且同意传递参数。

动用比较轻便,演示代码如下所示。演示了线程池使用中如何传递格局和参数,最终索要注意的是使用了Lambda表达式和它的闭包机制。

static void Main(string[] args)
{
    const int x = 1;
    const int y = 2;
    const string lambdaState = "lambda state 2";

    // 直接将方法传递给线程池
    ThreadPool.QueueUserWorkItem(AsyncOperation);
    Sleep(TimeSpan.FromSeconds(1));

    // 直接将方法传递给线程池 并且 通过state传递参数
    ThreadPool.QueueUserWorkItem(AsyncOperation, "async state");
    Sleep(TimeSpan.FromSeconds(1));

    // 使用Lambda表达式将任务传递给线程池 并且通过 state传递参数
    ThreadPool.QueueUserWorkItem(state =>
    {
        WriteLine($"Operation state: {state}");
        WriteLine($"工作线程 id: {CurrentThread.ManagedThreadId}");
        Sleep(TimeSpan.FromSeconds(2));
    }, "lambda state");

    // 使用Lambda表达式将任务传递给线程池 通过 **闭包** 机制传递参数
    ThreadPool.QueueUserWorkItem(_ =>
    {
        WriteLine($"Operation state: {x + y}, {lambdaState}");
        WriteLine($"工作线程 id: {CurrentThread.ManagedThreadId}");
        Sleep(TimeSpan.FromSeconds(2));
    }, "lambda state");

    ReadLine();
}

private static void AsyncOperation(object state)
{
    WriteLine($"Operation state: {state ?? "(null)"}");
    WriteLine($"工作线程 id: {CurrentThread.ManagedThreadId}");
    Sleep(TimeSpan.FromSeconds(2));
}

运营结果如下图所示。

图片 7

图片 8

2. System.Net.Sockets命名空间

 


5. 局部类型上的修饰符

本文由必赢网上注册发布于必赢网上注册,转载请注明出处:使用线程池,记录日志

关键词:

并实行多少级联转载,自定义日期的时分秒

1、在Python中要想定义的艺术只怕变量只在类内部采纳不被外表调用,能够在措施和变量前面加  两个  下划线 C# 结...

详细>>

NPOI管理Word文本中上下角标,异步总计

上述示例方法用到了八个类,如下:   public object AddMulitDeparment(IFormCollection files) { string[] colName = new string[] { "公司名...

详细>>

反射赋值的有关,HeadFirst设计形式中的笔记

写在前面 总体项目都托管在了 Github上: 寻找更为有扶助的本子见: 这风姿洒脱节内容大概会用到的库文件有 Quick,...

详细>>

python之常用模块,python框架之虚构意况的陈设

在付出进程中,往往同后生可畏台微型机要支付差别的品类,分化的类型或然要求区别版本的包,为了消除那几个标...

详细>>