xml地图|网站地图|网站标签 [设为首页] [加入收藏]
多线程编程系列,编程实现一键修改Hosts文件
分类:编程

目录

 

首先大家要知道在浏览器上浏览虚拟主机,必须使用Hosts文件或域名系统(DNS)实现主机名到IP地址的解析。在局域网中用Hosts文件或DNS都可以,在Internet上只能用DNS了。 

  • 1.1 简介
  • 1.2 在线程池中调用委托
  • 1.3 向线程池中放入异步操作
  • 1.4 线程池与并行度
  • 1.5 实现一个取消选项
  • 1.6 在线程池中使用等待事件处理器及超时
  • 1.7 使用计时器
  • 1.8 使用BackgroundWorker组件
  • 参考书籍
  • 笔者水平有限,如果错误欢迎各位批评指正!
 1  Bitmap bit= new Bitmap(@"" + Path);//给图片加边框
 2  //Bitmap bit = new Bitmap(Screen.AllScreens[0].Bounds.Size.Width, Screen.AllScreens[0].Bounds.Size.Height);//给当前桌面图加边框
 3  float w = (float)(bit.Width * 0.2);//边框的宽度,可取任意值
 4   using (Graphics g = Graphics.FromImage(bit))
 5   {
 6       // g.CopyFromScreen(0, 0, 0, 0, Screen.AllScreens[0].Bounds.Size);//抓取背景图
 7         using (Pen pen = new Pen(Color.White, w))
 8        { 
 9        //g.DrawRectangle(pen, new Rectangle(0, 0, Screen.AllScreens[0].Bounds.Size.Width, Screen.AllScreens[0].Bounds.Size.Height));//给当前桌面画白框
10         //g.DrawRectangle(pen, new Rectangle(0, 0, Math.Abs(bit.Width), Math.Abs(bit.Height)));//加边框
11          g.DrawEllipse(pen, new Rectangle(0, 0, Math.Abs(bit.Width), Math.Abs(bit.Height)));//加椭圆边框
12           g.Dispose();
13         // pic.BackgroundImage = bit;
14        } 
15    }

1.当用户输入一个域名以百度为例(www.baidu.com)。


 

2.首先会到C:WindowsSystem32driversetc目录中用Hosts文件去查询相关的IP是否存在,如果存在就会访问该IP地址。


3.不存在该域名解析,那么就会到公网DNS查找。

1.1 简介

在本章中,主要介绍线程池(ThreadPool)的使用;在C#中它叫System.Threading.ThreadPool,在使用线程池之前首先我们得明白一个问题,那就是为什么要使用线程池。其主要原因是创建一个线程的代价是昂贵的,创建一个线程会消耗很多的系统资源。

那么线程池是如何解决这个问题的呢?线程池在初始时会自动创建一定量的线程供程序调用,使用时,开发人员并不直接分配线程,而是将需要做的工作放入线程池工作队列中,由线程池分配已有的线程进行处理,等处理完毕后线程不是被销毁,而是重新回到线程池中,这样节省了创建线程的开销。

但是在使用线程池时,需要注意以下几点,这将非常重要。

  • 线程池不适合处理长时间运行的作业,或者处理需要与其它线程同步的作业。
  • 避免将线程池中的工作线程分配给I/O首先的任务,这种任务应该使用TPL模型。
  • 如非必须,不要手动设置线程池的最小线程数和最大线程数,CLR会自动的进行线程池的扩张和收缩,手动干预往往让性能更差。

当你访问域名出现异常,可能Hosts文件被修改了或者DNS被挟持了。

1.2 在线程池中调用委托

本节展示的是如何在线程池中如何异步的执行委托,然后将介绍一个叫异步编程模型(Asynchronous Programming Model,简称APM)的异步编程方式。

在本节及以后,为了降低代码量,在引用程序集声明位置默认添加了using static System.Consoleusing static System.Threading.Thead声明,这样声明可以让我们在程序中少些一些意义不大的调用语句。

演示代码如下所示,使用了普通创建线程和APM方式来执行同一个任务。

static void Main(string[] args)
{
    int threadId = 0;

    RunOnThreadPool poolDelegate = Test;

    var t = new Thread(() => Test(out threadId));
    t.Start();
    t.Join();

    WriteLine($"手动创建线程 Id: {threadId}");

    // 使用APM方式 进行异步调用  异步调用会使用线程池中的线程
    IAsyncResult r = poolDelegate.BeginInvoke(out threadId, Callback, "委托异步调用");
    r.AsyncWaitHandle.WaitOne();

    // 获取异步调用结果
    string result = poolDelegate.EndInvoke(out threadId, r);

    WriteLine($"Thread - 线程池工作线程Id: {threadId}");
    WriteLine(result);

    Console.ReadLine();
}

// 创建带一个参数的委托类型
private delegate string RunOnThreadPool(out int threadId);

private static void Callback(IAsyncResult ar)
{
    WriteLine("Callback - 开始运行Callback...");
    WriteLine($"Callback - 回调传递状态: {ar.AsyncState}");
    WriteLine($"Callback - 是否为线程池线程: {CurrentThread.IsThreadPoolThread}");
    WriteLine($"Callback - 线程池工作线程Id: {CurrentThread.ManagedThreadId}");
}

private static string Test(out int threadId)
{
    string isThreadPoolThread = CurrentThread.IsThreadPoolThread ? "ThreadPool - ": "Thread - ";

    WriteLine($"{isThreadPoolThread}开始运行...");
    WriteLine($"{isThreadPoolThread}是否为线程池线程: {CurrentThread.IsThreadPoolThread}");
    Sleep(TimeSpan.FromSeconds(2));
    threadId = CurrentThread.ManagedThreadId;
    return $"{isThreadPoolThread}线程池工作线程Id: {threadId}";
}

运行结果如下图所示,其中以Thread开头的为手动创建的线程输出的信息,而TheadPool为开始线程池任务输出的信息,Callback为APM模式运行任务结束后,执行的回调方法,可以清晰的看到,Callback的线程也是线程池的工作线程。

图片 1

在上文中,使用BeginOperationName/EndOperationName方法和.Net中的IAsyncResult对象的方式被称为异步编程模型(或APM模式),这样的方法被称为异步方法。使用委托的BeginInvoke方法来运行该委托,BeginInvoke接收一个回调函数,该回调函数会在任务处理完成后背调用,并且可以传递一个用户自定义的状态给回调函数。

现在这种APM编程方式用的越来越少了,更推荐使用任务并行库(Task Parallel Library,简称TPL)来组织异步API。

解决方案:

本文由澳门新葡亰手机版发布于编程,转载请注明出处:多线程编程系列,编程实现一键修改Hosts文件

上一篇:Python之爬虫总结,python框架之虚拟环境的配置 下一篇:直到云端,字符串反转
猜你喜欢
热门排行
精彩图文