好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C#多线程1

C#多线程1

MVC4的新增功能之前端优化

 

        做asp.net平台开发都能感觉到,微软更新速度很快。对于这点是好是坏各人的评价不尽相同。有的认为更新快是才能及时用上最新技术,有的又觉得更新快是由于不能一次性做得最好。本文简单讲一下mvc4中关于前端的一个新功能——js与css的压缩与合并。
在这之前,也有很多第三方工具可以来做这件事,MVC4中把该功能也集成上去了,可谓微软真的很贴心。
        mvc4中的这个功能是在System.Web.Optimization命名空间中。在MVC4的测试版跟RC版里也有所不同,这里只说RC版的。我们创建一个MVC4(RC)项目后,项目中会比以往的项目多了个App_Start目录,里面存放3个类,BundleConfig.cs、FilterConfig.cs、RouteConfig.cs。BundleConfig.cs就是用来配置这些css、js的。这里不详细介绍,只简单提一提用法。取两段简单的代码看一下:
bundles.Add(new ScriptBundle("~/bundles/jquery").Include("~/Scripts/jquery-1.*"));
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
这两个就是配置js路径跟css路径,当然路径可以有多个,Include传递的参数为数组。可以把要添加的js跟css都放上去。在View中引用方式是:
    @System.Web.Optimization.Styles.Render("~/Content/css")
    @System.Web.Optimization.Scripts.Render("~/bundles/jquery")
用法也比较简单。(MVC4测试版中稍微麻烦些,需要在Global.asax中注册。)
        好了,到这里就简单提一下MVC4的这一新增功能。然而本文主要不是要夸它一番,而是要稍微批它一下。下面说说这个功能一个不足的地方。
        我们在css中难免会用到很多背景图片之类的,假设我们有这杨一个样式表:
        /Content/themes/default/typography.css
里面定义了一个样式:  
        h1.logo{background:url(images/logo.png) top left no-repeat;} 我们引用了一张背景图片。
背景图片路径为:/Content/themes/default/images/logo.png。
同样我们将这个样式表也添加到配置中,这样写:
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"," /Content/themes/default/typography.css"));
在_layout.cshtml(或者view中也行)引用  @System.Web.Optimization.Styles.Render("~/Content/css"),当我们在web.config中启用调试模式时(<compilation debug="true" targetFramework="4.0"/>),此时打开页面,查看网页源文件,我们发现css代码并没有被压缩,页面中显示的是引用了两个css文件,此时图片也正常显示,没 任何问题。但是当我们不启用调试模式(<compilation debug="false" targetFramework="4.0"/>)时,css跟js代码会被压缩,不管我们里面添加了几个css,最终会被压缩成一个,出现类似这样的引用:
 <link href="/Content/css?v=jsX9ARrAsXtFSm5-ZAd0mrgR0YlAerOxMoONulX4Kd01" rel="stylesheet" type="text/css" /> 。打开这个路径看css源码,发现css样式已经被压缩了。这也就是我们想要得到的效果。但是此时图片并无法找到。
为何会这样?其实我们查看压缩后的css代码就可以知道了,因为压缩后css里面引用的图片路径并不会改变,依然是url(images/logo.png),那么此时css所表示的图片路径应该是在/Content/images/logo.png。而我们图片真正的路径是在:/Content/themes/default/images/logo.png。也难怪它找不到。如果压缩后样式是这样写的:h1.logo{background:url(themes/default/images/logo.png) top left no-repeat;} 就不会有问题了。可惜微软没做到,或者说暂时没做到。
    如果我们使用第三方组件,比如Combres来进行压缩,完全不会有这种问题,因为它压缩时可以重写路径。对于MVC4自带压缩功能的这个问题,我目前也只能为同一个目录下的样式表写成一组,这样当样式表在多个目录时页面中就要有多个<link href="cssurl" rel="stylesheet" type="text/css" />这样的代码了。这样页面载入时就要多做几次请求,但至少比不进行压缩好一些就是了。整体来说对于MVC4的几个新功能,个人觉得还是挺给力的。关于MVC4的新功能,各位可以看看微软的官方介绍(带视频):
http://weblogs.asp.net/jgalloway/archive/2012/02/16/asp-net-4-beta-released.aspx

本文来自风情波涌的博客  http://www.cnblogs.com/hahqb

C#序列化、反序列化学习

概念:

序列化就是将对象转换为可保持或传输的过程,与序列化相反的过程就是反序列化。

作用:

通过序列化可以很轻松的存储和传输对象。

三种序列化技术:

       .NET提供了三种序列化技术,我只知道这三种技术。分别是:Xml序列化、二进制序列化、Soap序列化(需要在项目内添加引用System.Runtime.Serialization.Formatters.Soap,然后在类中using这个引用。)

Xml序列化是将对象的公共属性和字段转换为序列格式并保存在Xml文件中。Xml反序列化则是将Xml中的数据重新生成对象。

二进制序列化指使用二进制编码生成精简的序列化,用于存储或基于套接字的网络流。二进制序列化保持类型保真度,这对于应用程序的不同调用之间保留对象的状态很有用。

Soap序列化是将对象序列化为符合Soap规范的Xml流。

序列化的步骤:

        1、创建对象,并设置公共属性和字段

      2、确定使用xml、二进制、Soap这三种方式中的哪种方式序列化对象。具体的步骤如下面的示例。

示例:

        1、新建解决方案Serializer

      2、新建类库Jack.Gao.Domain,并在该类库下添加Person类,Person类的代码如下:

View Code

      3、新建类库Jack.Gao.PersonFactory,在该库下新建Factory类,用于生成Person。代码如下:

View Code

          添加枚举类型SerializerType,代码如下:

View Code

             再新建一个类SerializerTypeFactory,添加如下代码:

View Code

        4、新建类库Jack.Gao.CreateSerializerType,新建ICreateSerializer接口和CreateSerializer类。
          ICreateSerializer的代码如下:

View Code

            CreateSerializer的代码如下:

View Code

       5、新建控制台输出程序Jack.Gao.AppSerializer,在Program.cs添加如下代码:

View Code

             运行该程序,可以看到在输出目录下多了一个Person.xml的文件,可以查看里面的内容,以下内容使用soap序列化后生成的,你也可以查看其它的两种方式生成的内容。

           

 

分类:  C#学习

标签:  C#学习

[.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();
            }
        } 

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

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

 源文件下载链接: https://files.cnblogs.com/zhili/FileServer.zip  (下载下来后只需要在服务器端Resources文件夹下添加一个文件就可以运行了)


    如果,您认为阅读这篇博客对你有帮助,点击一下右下角的 【推荐】 按钮。
    如果,你想了解我的动态,点击一下右下角的 【关注我】
    因为,你们的支持正是我学习的动力 

    如果对文章有任何问题,都可以再评论中留言,我会尽可能的答复您,谢谢你的阅读

分类:  Asp.net ,  C#多线程处理系列 ,  CLR

标签:  多线程 实现文件的下载

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于C#多线程1的详细内容...

  阅读:43次

上一篇: GFS架构分析

下一篇:触发器心得