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


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

    服务器端页面:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FileServer.Default" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>  
        <form id="form1" runat="server">
        <div>
        
        <asp:Image ID="Image1" runat="server" ImageUrl="~/Images/1.gif" />
        
            说明: CLR Via C#
            </div>
            
        </form>
    </body>
    </html>

    服务器页面只是一个简单显示需要下载文件的一些信息,这里通过Handler.ashx来处理文件的下载,把文件的转化为二进制字节写入到输出流中,具体实现代码为:

     public class Handle : IHttpHandler
        {
            public void ProcessRequest(HttpContext context)
            {
                HttpResponse response = context.Response;
                HttpRequest request = context.Request;
                FileStream fileStream = null;
                byte[] buffer = new Byte[10240];
                int length;
    
                // 剩余的字节大小
                // 因为这里采取的是每次写入10240字节到输出流中
                long readToData;
                try
                {
                    string filename = "CLR via CSharp 3rd edition.pdf"; //通过解密得到文件名
    
                    string filepath = HttpContext.Current.Server.MapPath("~/") + "Resources/" + filename; //待下载的文件路径
    
                    fileStream = new FileStream(filepath, FileMode.Open,FileAccess.Read, FileShare.Read);
                    readToData = fileStream.Length;
                    while (readToData > 0)
                    {
                        // 实际读取的字节大小
                        length = fileStream.Read(buffer, 0, buffer.Length);
                        // 把读取到的字节写入输出流中
                        response.OutputStream.Write(buffer, 0, length);
                        response.Flush();
                        readToData = readToData - length;
                    }
                }
                catch (Exception ex)
                {
                    response.Write("Error:" + ex.Message);
                }
                finally
                {
                    if (fileStream != null)
                    {
                        fileStream.Close();
                    }
    
                    response.End();
                }
            }
    
            public bool IsReusable
            {
                get
                {
                    return false;
                }
            }
        }

    这里牵涉到HttpHandle对象问题,这个对象在Asp.net中是真正处理数据的对象,后面如果有时间也和大家分享下深入理解Asp.net系列,主要是介绍在Asp.net中一些核心对象为我们默默做的一些事情,在这里也不详细介绍HttpHandle对象了, 这个示例中主要通过这个类来对文件的处理,把文件的二进制字节写入到输出流中, 客户端在从输出流中读取字节,然后保存为文件(其实文件也就是“流”)。

    客户端:

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

    public void DownLoad(object state)
            {
                // 计时对象
                Stopwatch sw = Stopwatch.StartNew();
    
                HttpWebRequest request;
                HttpWebResponse response;
                Stream stream;
    
                // 下载下来的保存的地址
                string savepath = "D:\\Download.pdf";
                FileStream savestream = new FileStream(savepath, FileMode.OpenOrCreate);
                try
                {
                    // 发出请求
                    request = (HttpWebRequest)HttpWebRequest.Create(url);
    
                    // 获得回应对象
                    response = (HttpWebResponse)request.GetResponse();
    
                    // 获得回应流
                    stream = response.GetResponseStream();
                    byte[] bytes = new byte[10240];
                    int readsize;
    
                    // 每次都读取10240字节
                    // 采用的是同步读取方法
                    // 计算耗费的时间             
                    readsize = stream.Read(bytes, 0, bytes.Length);
                    while (readsize > 0)
                    {
                        savestream.Write(bytes, 0, readsize);
                        readsize = stream.Read(bytes, 0, bytes.Length);
                    }
    
                    sw.Stop();
                    MessageBox.Show("下载耗时为:" + sw.Elapsed.ToString(), "提示");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error");
                }
                finally
                {
                    savestream.Close();
                }
            }

    这样就利用线程池线程简单完成了客户端下载服务器端文件的功能,并且使用线程池线程这样不会主线程,从而导致在下载文件时,界面同样可以操作,如果不采用多线程操作的话将会在下载过程导致界面“卡死”现象,这样就会给用户带来不好的用户体验。

     源文件下载链接:https://files.cnblogs.com/zhili/FileServer.zip 

  • 相关阅读:
    考察数据结构(An Extensive Examination of Data Structures)
    考察数据结构——第一部分:数据结构简介[译]
    老生常谈
    使用DataSet的ReadXml和WriteXml方法
    要掌握Sql Server,我还差得远啊!
    新浪短信Web Service
    还是水晶报表
    两种报表组件的功能分析
    无限级分类(非递归算法/存储过程版/GUID主键)完整数据库示例_(4)显示记录
    c#方法中调用参数的值传递方式和引用传递方式,以及ref与out的区别
  • 原文地址:https://www.cnblogs.com/ShaYeBlog/p/2705282.html
Copyright © 2020-2023  润新知