[c#]多线程网络编程应用程序[多线程文章采集]

优采云 发布时间: 2020-08-08 06:57

  编程不能死记硬背,取决于实践.

  如今,Internet越来越发达,共享文件变得如此简单. 特别是使用eDonkey和Thunder等下载软件时,它的功能更加强大. 如果要从Internet下载几G大小的文件,这确实很轻松. 好吧,废话太多,让我们今天直接进入我们的话题.

  要实现迅雷之类的多线程下载,核心问题是阐明多线程的概念以及如何实现.

  当然,本文的技术含量很低,因此请直接绕过它.

  多线程是相对单线程的. 有关详细信息,请参阅百度百科中的说明:

  每个程序都运行一个基本主线程,该主线程用于处理界面绘制,人机交互,后台处理和其他过程. 因此,如果这在单线程程序中是一项耗时的操作,则主界面将被卡住,甚至无法工作. 因此,无论您是否喜欢,最好不要使用主线程来处理所有事情,否则将很难为用户提供舒适的客户体验.

  那么如何在C#中实现多线程?

  让我们实现以下最简单的多线程示例;

  为了便于演示,我们创建了一个新的winform项目,名为MultiThreadDemo.

  

  首先创建一个足以使您的程序陷入困境的方法功能:

   private void Display()

{

while (true)

textBox1.Text = new Random().NextDouble().ToString();

}

  然后将一个调用添加到button1,发现它确实卡住了. 谁希望您让无尽的循环留给主线程来做呢?您画一幅画并数数,没有时间回复.

  using System.Threading;

  接下来,在button1中添加代码并为其创建一个线程. 我们将此线程称为“ UiThread”以处理显示.

  

  

  查看代码

   private void button1_Click(object sender, EventArgs e)

{

Thread thread = new Thread(Display);//创建一个线程

thread.Start();

// Display();

}

  如果您急着奔跑,您一定会回来骂我,为什么不呢?是否会提示: “线程间操作无效: 创建控件“ textBox1”的线程从不访问它. ”. 因为主线程和您创建的线程是两个不相关的线程,所以两个陌生人如何处理?也就是说,当您的UiThread在未经主线程同意的情况下调用textBox1时,其他人会允许您这样做吗?

  因此,为了处理其工作不一致的问题,专门强制取消了线程警告. 在构造函数中添加一个句子:

   public Form1()

{

InitializeComponent();

Control.CheckForIllegalCrossThreadCalls = false;//加上这句就不会警告了

}

  这样一个简单的多线程程序诞生了. 但是有时候有很多代码需要使用委托,并且您不想单独创建一个函数,可以这样做:

  

  

  查看代码

  private void button1_Click(object sender, EventArgs e)

{

ThreadStart threadStart = new ThreadStart(delegate { Display(); });//创建一个委托,这样可以调用任意参数的函数了,甚至是零星的代码都可以

Thread thread = new Thread(threadStart);

thread.Start();

}

  但是不建议这样做,因为它在线程上不安全,很有可能导致程序崩溃.

  通过以上练习,我们知道创建线程可以做更多的事情. 同样,如果我们创建更多线程,我们是否还要执行更多操作?有必要.

  接下来,我们今天将正式进入我们的主题: 多线程集合

  如果要使用多线程集合,则必须首先解决一个下载问题.

  using System.Net;

using System.IO;

  

  

  查看代码

   ///

/// 转载请加上本人博客链接

///

///

///

static void Request(RichTextBox richtextBox,int i)

{

richtextBox.AppendText(string.Format("线程{0}开始接收\n", Thread.CurrentThread.Name));

ServicePointManager.DefaultConnectionLimit = 1000;

HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(string.Format("http://news.cnblogs.com/n/{0}/", (int)i));//这里的i最嗨是158100到158999,符合博客园url规则才能采集到

StreamWriter sw = File.CreateText(string.Format(Environment.CurrentDirectory + "\\{0}.htm", i));

try

{

HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

Stream stream = httpWebResponse.GetResponseStream();

StreamReader sr = new StreamReader(stream);

string html = sr.ReadToEnd();

richtextBox.AppendText(string.Format(Thread.CurrentThread.Name + "接收完毕"));

sw.Write(html);

sw.Close();

}

catch

{

richtextBox.AppendText(string.Format("线程{0}不存在此地址,跳过\n", Thread.CurrentThread.Name));

sw.Write(string.Format("线程{0}不存在此地址,跳过\n", Thread.CurrentThread.Name));

return;

}

}

  然后在button2中呼叫

  

  

  查看代码

   private void button2_Click(object sender, EventArgs e)

{

ThreadStart threadStart = new ThreadStart(delegate { Request(richTextBox1, 158100); });//创建一个委托,这样可以调用任意参数的函数了,甚至是零星的代码都可以

Thread thread = new Thread(threadStart);

thread.Start();

}

  通过这种方式,可以完成一个集合.

  如果您想像优采云一样采集,自然不可能在当前水平上采集. 至少应进行批量采集. 仅仅是使用多线程.

  

  

  查看代码

   ///

/// 转载请加上本人博客链接

///

///

///

static void Request(RichTextBox richtextBox,int i)

{

richtextBox.AppendText(string.Format("线程{0}开始接收\n", Thread.CurrentThread.Name));

ServicePointManager.DefaultConnectionLimit = 1000;

HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(string.Format("http://news.cnblogs.com/n/{0}/", (int)i));//这里的i最嗨是158100到158999,符合博客园url规则才能采集到

try

{

HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

Stream stream = httpWebResponse.GetResponseStream();

StreamReader sr = new StreamReader(stream);

string html = sr.ReadToEnd();

richtextBox.AppendText(string.Format(Thread.CurrentThread.Name + "接收完毕\n"));

StreamWriter sw = File.CreateText(string.Format(Environment.CurrentDirectory + "\\{0}.htm", i));

sw.Write(html);

sw.Close();

}

catch

{

richtextBox.AppendText(string.Format("线程{0}不存在此地址,跳过\n", Thread.CurrentThread.Name));

}

}

private void button2_Click(object sender, EventArgs e)

{

Thread.CurrentThread.Name = "主线程";

Thread[] threads = new Thread[51];

DateTime endTime = DateTime.Now;

DateTime startTime = DateTime.Now;

TimeSpan timeSpan = endTime - startTime;

string span = timeSpan.TotalSeconds.ToString();

startTime = DateTime.Now;

Mutex mt = new Mutex();

mt.WaitOne();

for (int i = 158300; i >158250; i--)

{

threads[158300 - i] = new Thread(new ParameterizedThreadStart(delegate { Request(richTextBox1, i); }));

threads[158300 - i].Name = "线程" + (i).ToString(); ;

threads[158300 - i].Start();

}

mt.ReleaseMutex();

endTime = DateTime.Now;

timeSpan = endTime - startTime;

span = timeSpan.TotalSeconds.ToString();

richTextBox1.AppendText(string.Format("多线程接受的话共花费了{0}秒钟\n", span));

}

  多线程采集已完成. 实际上,本文主要是关于创建线程的主题,并且技术含量很低,所以让我们为刚刚起步的朋友们练习吧!

  

  该教程每天都会更新,请继续关注.

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线