[.Net 多线程处理系列专题七——对多线程的补充

简介:

因为有些人可能会疑惑,讲了这么多 多线程,到底在实际的应用上有什么作用的呢? 这里我在这里用多线程简单实现了一个文件的下载的功能。

服务器端页面:

 
  1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FileServer.Default" %> 
  2.  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
  4.  
  5. <html xmlns="http://www.w3.org/1999/xhtml"> 
  6. <head runat="server"> 
  7.     <title></title> 
  8. </head> 
  9. <body>    
  10.     <form id="form1" runat="server"> 
  11.     <div> 
  12.     <asp:Image ID="Image1" runat="server" ImageUrl="~/Images/1.gif" /> 
  13.       
  14.         说明: CLR Via C#  
  15.         </div>    
  16.     </form> 
  17. </body> 
  18. </html> 
服务器页面只是一个简单显示需要下载文件的一些信息,这里通过Handler.ashx来处理文件的下载,把文件的转化为二进制字节写入到输出流中,具体实现代码为: 

 
 
  1. public class Handle : IHttpHandler  
  2.     {  
  3.         public void ProcessRequest(HttpContext context)  
  4.         {  
  5.             HttpResponse response = context.Response;  
  6.             HttpRequest request = context.Request;  
  7.             FileStream fileStream = null;  
  8.             byte[] buffer = new Byte[10240];  
  9.             int length;  
  10.  
  11.             // 剩余的字节大小  
  12.             // 因为这里采取的是每次写入10240字节到输出流中  
  13.             long readToData;  
  14.             try 
  15.             {  
  16.                 string filename = "CLR via CSharp 3rd edition.pdf"//通过解密得到文件名  
  17.  
  18.                 string filepath = HttpContext.Current.Server.MapPath("~/") + "Resources/" + filename; //待下载的文件路径  
  19.  
  20.                 fileStream = new FileStream(filepath, FileMode.Open,FileAccess.Read, FileShare.Read);  
  21.                 readToData = fileStream.Length;  
  22.                 while (readToData > 0)  
  23.                 {  
  24.                     // 实际读取的字节大小  
  25.                     length = fileStream.Read(buffer, 0, buffer.Length);  
  26.                     // 把读取到的字节写入输出流中  
  27.                     response.OutputStream.Write(buffer, 0, length);  
  28.                     response.Flush();  
  29.                     readToData = readToData - length;  
  30.                 }  
  31.             }  
  32.             catch (Exception ex)  
  33.             {  
  34.                 response.Write("Error:" + ex.Message);  
  35.             }  
  36.             finally 
  37.             {  
  38.                 if (fileStream != null)  
  39.                 {  
  40.                     fileStream.Close();  
  41.                 }  
  42.  
  43.                 response.End();  
  44.             }  
  45.         }  
  46.  
  47.         public bool IsReusable  
  48.         {  
  49.             get 
  50.             {  
  51.                 return false;  
  52.             }  
  53.         }  
  54.     } 
    这里牵涉到HttpHandle对象问题, 这个对象在Asp.net中是真正处理数据的对象,后面如果有时间也和大家分享下深入理解Asp.net系列,主要是介绍在Asp.net中一些核心对象为我们默默做的一些事情,在这里也不详细介绍HttpHandle对象了, 这个示例中主要通过这个类来对文件的处理,把文件的二进制字节写入到输出流中, 客户端在从输出流中读取字节,然后保存为文件(其实文件也就是“流”)。

客户端:

客户端建立了一个WinForm窗口,通过WebBrower控件(就是在WinForm程序中显示网页的控件)来连接服务器页面,当按下下载按钮后,通过线程池线程来执行下载方法。主要代码为:

 
  1. public void DownLoad(object state)  
  2.         {  
  3.             // 计时对象  
  4.             Stopwatch sw = Stopwatch.StartNew();  
  5.  
  6.             HttpWebRequest request;  
  7.             HttpWebResponse response;  
  8.             Stream stream;  
  9.  
  10.             // 下载下来的保存的地址  
  11.             string savepath = "D:\\Download.pdf";  
  12.             FileStream savestream = new FileStream(savepath, FileMode.OpenOrCreate);  
  13.             try 
  14.             {  
  15.                 // 发出请求  
  16.                 request = (HttpWebRequest)HttpWebRequest.Create(url);  
  17.  
  18.                 // 获得回应对象  
  19.                 response = (HttpWebResponse)request.GetResponse();  
  20.  
  21.                 // 获得回应流  
  22.                 stream = response.GetResponseStream();  
  23.                 byte[] bytes = new byte[10240];  
  24.                 int readsize;  
  25.  
  26.                 // 每次都读取10240字节  
  27.                 // 采用的是同步读取方法  
  28.                 // 计算耗费的时间               
  29.                 readsize = stream.Read(bytes, 0, bytes.Length);  
  30.                 while (readsize > 0)  
  31.                 {  
  32.                     savestream.Write(bytes, 0, readsize);  
  33.                     readsize = stream.Read(bytes, 0, bytes.Length);  
  34.                 }  
  35.  
  36.                 sw.Stop();  
  37.                 MessageBox.Show("下载耗时为:" + sw.Elapsed.ToString(), "提示");  
  38.             }  
  39.             catch (Exception ex)  
  40.             {  
  41.                 MessageBox.Show(ex.Message, "Error");  
  42.             }  
  43.             finally 
  44.             {  
  45.                 savestream.Close();  
  46.             }  
  47.         } 
     这样就利用线程池线程简单完成了客户端下载服务器端文件的功能,并且使用 线程池线程这样不会 阻塞主线程,从而导致在下载文件时,界面同样可以操作, 如果不采用多线程操作的话将会在下载过程导致界面“卡死”现象,这样就会给用户带来不好的用户体验

    其实本来还想做复杂点的, 开始想实现的功能,是服务器端断点续传,然后客户端多线程下载的功能的,这个示例中只用到了一个线程池线程来完成下载任务,本来想通过执行多个线程池线程来完成下载任务的, 每个线程只负责一部分的读取工作, 然后把每个线程中读取的字节合并起来就是完整的文件字节了,但是这里遇到一个问题,怎么在服务器端实现续传的功能的, 客户端通过AddRange方法来发出部分读取请求,然后服务器端就要对请求头Range进行解析的,实现原理我还是清楚,但是在做的过程中还是出现了问题。所以这里只能分享一个简单的下载文件的功能给大家了, 至于多线程的下载和断点续传和大文件的上传等问题,等我学习了再和大家分享, 如果有大牛可以帮助我解决服务端断点续传的问题的话,欢迎留言。

 





     本文转自LearningHard 51CTO博客,原文链接:http://blog.51cto.com/learninghard/1034798,如需转载请自行联系原作者

相关文章
|
16天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
28天前
|
存储 缓存 NoSQL
Redis单线程已经很快了6.0引入多线程
Redis单线程已经很快了6.0引入多线程
31 3
|
30天前
|
消息中间件 安全 Linux
线程同步与IPC:单进程多线程环境下的选择与权衡
线程同步与IPC:单进程多线程环境下的选择与权衡
58 0
|
1天前
|
安全 算法 Java
JavaSE&多线程&线程池
JavaSE&多线程&线程池
15 7
|
2天前
|
存储 缓存 NoSQL
为什么Redis使用单线程 性能会优于多线程?
在计算机领域,性能一直都是一个关键的话题。无论是应用开发还是系统优化,我们都需要关注如何在有限的资源下,实现最大程度的性能提升。Redis,作为一款高性能的开源内存数据库,因其出色的单线程性能而备受瞩目。那么,为什么Redis使用单线程性能会优于多线程呢?
15 1
|
23天前
|
安全 Java 容器
Java并发编程:实现高效、线程安全的多线程应用
综上所述,Java并发编程需要注意线程安全、可见性、性能等方面的问题。合理使用线程池、同步机制、并发容器等工具,可以实现高效且线程安全的多线程应用。
14 1
|
24天前
|
JavaScript 前端开发
JS 单线程还是多线程,如何显示异步操作
JS 单线程还是多线程,如何显示异步操作
22 2
|
1月前
|
消息中间件 Java 数据库连接
【C++ 多线程】C++ 多线程环境下的资源管理:深入理解与应用
【C++ 多线程】C++ 多线程环境下的资源管理:深入理解与应用
38 1
|
1月前
|
Java API C++
【C++ 与Qt 线程】C++ std::thread 与Qt qthread多线程混合编程
【C++ 与Qt 线程】C++ std::thread 与Qt qthread多线程混合编程
45 1
|
1月前
|
消息中间件 算法 开发者
【Qt面试题】多线程情况下, Qt中的信号槽分别在什么线程中执行, 如何控制?
【Qt面试题】多线程情况下, Qt中的信号槽分别在什么线程中执行, 如何控制?
20 1

热门文章

最新文章