RSS 2.0 Feed

Friday, August 29, 2008

今天碰到了一个超级怪异的问题, Visual Studio 调试一段代码时,如下图:监视窗口显示这个变量有值,但是代码却执行到这个变量无值的逻辑中了。

为了这个问题,我简直疯了。

后来看到其中一些变量的察看时,会报错误

Cannot obtain value of local or argument 'oo' as it is not available at this instruction pointer, possibly because it has been optimized away.

在装配脑袋的提醒下,觉得可能是Visual Studio的代码优化导致了这个问题。

取消编译时候的代码优化。 再Debug,就没有这个问题。

竟然是代码优化导致了这个让我困扰了一下午的问题。

代码优化取消在下面位置, 取消 Optimize code 之前的 CheckBox 即可。黄线上面的选项

posted @ | Feedback (0) | Filed Under [ .net 编程心得 技术随笔 .net 3.0 .net 3.5 ]

Thursday, August 28, 2008

我们在调试GAC中部署的程序时候,很可能碰到下面的报告:

---------------------------
Microsoft Visual Studio
---------------------------
The following module was built either with optimizations enabled or without debug information:

C:\Windows\assembly\GAC_MSIL\CSDN.Community.TopicListDataCenter.EnterpriseComponents\2.5.1.23407__cdde601ea7585548\aaa.dll

To debug this module, change its project build configuration to Debug mode. To suppress this message, disable the 'Warn if no user code on launch' debugger option.
---------------------------
确定  
---------------------------

这是因为VS开发工具在C:\Windows\assembly\GAC_MSIL\CSDN.Community.TopicListDataCenter.EnterpriseComponents\目录下没有找到aaa.pdb调试符号文件。当然这个目录是GAC的目录,不可能有的。

如何解决,最笨的方法是吧 PDB 文件 Copy 到那个目录去。

我这里要说的解决方法当然不是这样的了。而是如下:

在Visual Studio 的调试属性中去掉 Enable Just My Code(Managed only)

这时候我们再去调试就不会出现上述提示文本了。也不会找不到 PDB文件了。一切都OK了。

我们在Modules窗口也可以看到成功加载了正确位置的pdb文件。

 

 

参考资料:

You Don't Need to Copy PDB Files to Debug in the GAC!
http://www.elumenotion.com/Blog/Lists/Posts/Post.aspx?ID=23

posted @ | Feedback (0) | Filed Under [ .net 编程心得 技术随笔 .net 3.0 .net 3.5 ]

Thursday, August 07, 2008

写个非技术的。

奥运会点燃主火炬的我猜是“体操王子”李宁。

点火方式我猜会吊钢丝,类似中国功夫的凌波微步,或者叫凤回巢的方式飞过去。

李宁的照片,看起来老了。

posted @ | Feedback (1) | Filed Under [ 非技术随笔 ]

Wednesday, July 30, 2008

       阅读本博客前,建议阅读我前一篇博客:IIS5、IIS6、IIS7的ASP.net 请求处理过程比较  这样知识会比较连贯。

       对于 IIS6、IIS7,  每个应用程序池都会创建一个 W3WP.exe 进程。  但是, 并不是所有情况都是一个应用程序池对应一个 W3WP.exe 进程。 Web Garden , 或者一些异常发生时候,就会一个 应用程序池对应多个 W3WP.exe 进程。

 

       Web Garden 指的是一个应用程序可以在多个进程(w3wp.exe)中来执行,一次请求使用其中的一个。用这个的主要目的是提高程序的可用性。当其中一个进程发生错误,那么也不会影响其他进程。发生错误的进程可以根据规则关闭,而其他的进程则可以继续工作。

       需要注意的是:一般使用 InProc HttpSessionState / HttpApplicationState / 静态变量来储存关键信息 的程序是不支持 Web Garden的。

 

       由于应用程序池会在没有请求的时候定时回收,或者发生错误的时候,自动重新建立一个处理进程 W3WP.exe 进程。如果你中大运,你可能会看到没有配置 Web Garden 时, 一个应用程序池对应多个 W3WP.exe 进程, 如这篇文章中提到的 http://www.eggheadcafe.com/forumarchives/inetserveriis/Feb2006/post25881024.asp

       

IIS 6 (Win2003 )中查看某个应用程序池对应那个 W3WP.exe 进程,可以使用如下命令,输出结果类似如下:

C:\WINDOWS\system32>cscript iisapp.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
W3WP.exe PID: 1172 AppPoolId: StsAdminAppPool
W3WP.exe PID: 2656 AppPoolId: MSSharePointAppPool
W3WP.exe PID: 2148 AppPoolId: WMS App Pool
W3WP.exe PID: 3604 AppPoolId: defaultwebsite

参看这篇博客: http://blogs.msdn.com/jb/archive/2006/02/22/536693.aspx

 

IIS 7 中则是如下命令,输出结果类似如下:

C:\Windows\system32>%windir%/system32/inetsrv/appcmd list wp
WP “5716″ (applicationPool:DefaultAppPool)
WP “968″ (applicationPool:MyOtherAppPool)
WP “5836″ (applicationPool:TheThirdAppPool)

参看: http://dirk.net/2008/06/01/identify-which-w3wpexe-belongs-to-which-application-pool-in-iis7/

 

参考资料:

找出“w3wp.exe进程”对应的“应用程序池”
http://www.cnblogs.com/windpole/archive/2007/11/19/964819.html

Which w3wp.exe process belongs to which App Pool in IIS6
http://weblogs.asp.net/owscott/archive/2004/09/21/Which-w3wp.exe-process-belongs-to-which-App-Pool-in-IIS6.aspx

What Application Pool does this W3WP.EXE belong to?
http://blogs.msdn.com/jb/archive/2006/02/22/536693.aspx

New in IIS 7 - App Pool Isolation
http://adopenstatic.com/cs/blogs/ken/archive/2008/01/29/15759.aspx

对w3wp.exe的一点认识!
http://www.cnblogs.com/hjh1982/archive/2006/06/28/438032.html

关于Web Garden与Web Farms
http://www.cnblogs.com/huashanlin/archive/2007/07/30/836652.html

你的程序支持 IIS6 - Web Garden 吗?
http://blog.joycode.com/lostinet/archive/2005/02/02/44017.aspx

Web Farm And Web Garden
http://www.cnblogs.com/kingclever/archive/2007/12/13/993152.html

Identify which w3wp.exe belongs to which Application Pool in IIS7
http://dirk.net/2008/06/01/identify-which-w3wpexe-belongs-to-which-application-pool-in-iis7/

posted @ | Feedback (0) | Filed Under [ .net 编程心得 技术随笔 网站开发管理相关内容 .net 3.5 ]

Friday, July 25, 2008

ASP.NET是一个非常强大的构建Web应用的平台,它提供了极大的灵活性和能力以致于可以用它来构建所有类型的Web应用。
绝大多数的人只熟悉高层的框架如: WebForms 和 WebServices --这些都在ASP.NET层次结构在最高层。

这篇文章的资料收集整理自各种微软公开的文档,通过比较 IIS5、IIS6、IIS7 这三代 IIS 对请求的处理过程, 让我们熟悉 ASP.NET的底层机制 并对请求(request)是怎么从Web服务器传送到ASP.NET运行时有所了解。通过对底层机制的了解,可以让我们对 ASP.net 有更深的理解。

IIS 5 的 ASP.net 请求处理过程

对图的解释:

IIS 5.x 一个显著的特征就是 Web Server 和真正的 ASP.NET Application 的分离。作为 Web Server 的IIS运行在一个名为 InetInfo.exe 的进程上,InetInfo.exe 是一个Native Executive,并不是一个托管的程序,而我们真正的 ASP.NET Application 则是运行在一个叫做 aspnet_wp 的 Worker Process 上面,在该进程初始化的时候会加载CLR,所以这是一个托管的环境。

ISAPI:  指能够处理各种后缀名的应用程序。 ISAPI 是下面单词的简写 :Internet Server Application Programe Interface,互联网服务器应用程序接口。

IIS 5 模式的特点:

1、首先,同一台主机上在同一时间只能运行一个 aspnet_wp 进程,每个基于虚拟目录的 ASP.NET Application 对应一个 Application Domain ,也就是说每个 Application 都运行在同一个 Worker Process 中,Application之间的隔离是基于 Application Domain 的,而不是基于Process的。

2、其次,ASP.NET  ISAPI 不但负责创建 aspnet_wp Worker Process,而且负责监控该进程,如果检测到 aspnet_wp 的 Performance 降低到某个设定的下限,ASP.NET  ISAPI 会负责结束掉该进程。当 aspnet_wp 结束掉之后,后续的 Request 会导致ASP.NET ISAPI 重新创建新的 aspnet_wp Worker Process。

3、最后,由于 IIS 和 Application 运行在他们各自的进程中,他们之间的通信必须采用特定的通信机制。本质上 IIS 所在的 InetInfo 进程和 Worker Process 之间的通信是同一台机器不同进程的通信(local interprocess communications),处于Performance的考虑,他们之间采用基于Named pipe的通信机制。ASP.NET ISAPI和Worker Process之间的通信通过他们之间的一组Pipe实现。同样处于Performance的原因,ASP.NET ISAPI 通过异步的方式将Request 传到Worker Process 并获得 Response,但是 Worker Process 则是通过同步的方式向 ASP.NET ISAPI 获得一些基于 Server 的变量。

 

IIS6 的 ASP.net 请求处理过程

对图的解释:

IIS 5.x 是通过 InetInfo.exe 监听 Request 并把Request分发到Work Process。换句话说,在IIS 5.x中对Request的监听和分发是在User Mode中进行,在IIS 6中,这种工作被移植到kernel Mode中进行,所有的这一切都是通过一个新的组件:http.sys 来负责。

注:为了避免用户应用程序访问或者修改关键的操作系统数据,windows提供了两种处理器访问模式:用户模式(User Mode)和内核模式(Kernel Mode)。一般地,用户程序运行在User mode下,而操作系统代码运行在Kernel Mode下。Kernel Mode的代码允许访问所有系统内存和所有CPU指令。

在User Mode下,http.sys接收到一个基于 aspx 的http request,然后它会根据IIS中的 Metabase 查看该基于该 Request 的 Application 属于哪个Application Pool, 如果该Application Pool不存在,则创建之。否则直接将 request 发到对应Application Pool 的 Queue中。

每个 Application Pool 对应着一个Worker Process:w3wp.exe,毫无疑问他是运行在User Mode下的。在IIS Metabase 中维护着 Application Pool 和worker process的Mapping。WAS(Web Administrative service)根据这样一个mapping,将存在于某个Application Pool Queue的request 传递到对应的worker process(如果没有,就创建这样一个进程)。在 worker process 初始化的时候,加载ASP.NET ISAPI,ASP.NET ISAPI 进而加载CLR。最后的流程就和IIS 5.x一样了:通过AppManagerAppDomainFactory 的 Create方法为 Application 创建一个Application Domain;通过 ISAPIRuntime 的 ProcessRequest处理Request,进而将流程进入到ASP.NET Http Runtime Pipeline。

 

IIS 7  的 ASP.net 请求处理过程

 

IIS7 站点启动并处理请求的步骤如下图:

步骤 1 到 6 ,是处理应用启动,启动好后,以后就不需要再走这个步骤了。

上图的8个步骤分别如下:

1、当客户端浏览器开始HTTP 请求一个WEB 服务器的资源时,HTTP.sys 拦截到这个请求。
2、HTTP.sys contacts WAS to obtain information from the configuration store.

3、WAS 向配置存储中心请求配置信息。applicationHost.config。
4、WWW 服务接受到配置信息,配置信息指类似应用程序池配置信息,站点配置信息等等。
5、WWW 服务使用配置信息去配置 HTTP.sys 处理策略。
6、WAS starts a worker process for the application pool to which the request was made.

7、The worker process processes the request and returns a response to HTTP.sys.

8、客户端接受到处理结果信息。

W3WP.exe 进程中又是如果处理得呢?? IIS 7 的应用程序池的托管管道模式分两种: 经典和集成。 这两种模式下处理策略各不相通。

本文作者:郭红俊 http://blog.joycode.com/ghj

 

IIS 6 以及 IIS7 经典模式的托管管道的架构

       在IIS7之前,ASP.NET 是以 IIS ISAPI extension 的方式外加到 IIS,其实包括 ASP 以及 PHP,也都以相同的方式配置(PHP 在 IIS 采用了两种配置方式,除了 IIS ISAPI extension 的方式,也包括了 CGI 的方式,系统管理者能选择 PHP 程序的执行方式),因此客户端对 IIS 的 HTTP 请求会先经由 IIS 处理,然后 IIS 根据要求的内容类型,如果是 HTML 静态网页就由 IIS 自行处理,如果不是,就根据要求的内容类型,分派给各自的 IIS ISAPI extension;如果要求的内容类型是 ASP.NET,就分派给负责处理 ASP.NET 的 IIS ISAPI extension,也就是 aspnet_isapi.dll。下图是这个架构的示意图。

IIS  7 应用程序池的 托管管道模式  经典  模式也是这样的工作原理。 这种模式是兼容IIS 6 的方式, 以减少升级的成本。

IIS6 的执行架构图,以及 IIS7  应用程序池配置成经典模式的执行架构图

 

IIS  7 应用程序池的 托管管道模式  集成模式

       而 IIS 7 完全整合 .NET 之后,架构的处理顺序有了很大的不同(如下图),最主要的原因就是 ASP.NET 从 IIS 插件(ISAPI extension)的角色,进入了 IIS 核心,而且也能以 ASP.NET 模块负责处理 IIS 7 的诸多类型要求。这些 ASP.NET 模块不只能处理 ASP.NET 网页程序,也能处理其他如 ASP 程序、PHP 程序或静态 HTML 网页,也因为 ASP.NET 的诸多功能已经成为 IIS 7 的一部份,因此 ASP 程序、PHP 程序或静态 HTML 网页等类型的要求,也能使用像是Forms认证(Forms Authentication)或输出缓存(Output Cache)等 ASP.NET 2.0 的功能(但须修改 IIS 7 的设定值)。也因为 IIS 7 允许自行以 ASP.NET API 开发并加入模块,因此 ASP.NET 网页开发人员将更容易扩充 IIS 7 和网站应用程序的功能,甚至能自行以 .NET 编写管理 IIS 7 的程序(例如以程控 IIS 7 以建置网站或虚拟目录)。

IIS 7 的执行架构图(集成托管信道模式下的架构)

 

小结

IIS5 到 IIS6 的改进,主要是 HTTP.sys 的改进。

IIS6 到 IIS7 的改进,主要是 ISAPI 的改进。

 

参考资料:

ASP.NET Process Model之一:IIS 和 ASP.NET ISAPI
http://www.cnblogs.com/artech/archive/2007/09/09/887528.html

ASP.NET Internals – IIS and the Process Model
http://dotnetslackers.com/articles/iis/ASPNETInternalsIISAndTheProcessModel.aspx

模组化的IIS 7 与.NET 能力整合
http://www.microsoft.com/taiwan/technet/columns/profwin/33-iis7-componentization-integration.mspx

Introduction to IIS 7.0 Architecture
http://learn.iis.net/page.aspx/101/introduction-to-iis7-architecture/

posted @ | Feedback (1) |

Wednesday, July 23, 2008

问题:当一个正在执行中的ASPX页面执行到一半的时候,浏览器中你关闭了这个页面,服务器端对应的这个页面的代码仍然在执行么?

答案:除非你代码里面做了特殊判断,否则仍然正在执行。

 

注意点:

1、客户端显示页面的时候,后台已经执行完了的页面对象早已经不存在了。当然这时候谈不上服务器段执行不执行的问题了。

2、页面还没有返回,处于等待状态的时候。关闭ASPX页面,才会涉及到上面提到的服务器端仍然在执行的情况。

3、客户端关闭的时候根本不向服务器发送指令。

4、除非你代码里面做了特殊判断,这里的特殊判断指用 if(!Response.IsClientConnected) 来检测状态而用代码终止运行。

下面的简单代码就是演示关闭页面后,看是否仍然在执行?

你可以在这个页面打开后, 还没有返回任何信息的时候把这个页面关闭,然后看指定目录下是否有对应文件被创建并填写内容。

        protected void Page_Load(object sender, EventArgs e)
        {
            StringBuilder txt = new StringBuilder();

            txt.AppendLine();
            txt.AppendLine(DateTime.Now.ToString("u"));
            txt.AppendLine("asvd");

            Response.Write(DateTime.Now.ToString("u"));
            Response.Write("<br />\r\n");
            Thread.Sleep(50000);


            txt.AppendLine(DateTime.Now.ToString("u"));
            Response.Write(DateTime.Now.ToString("u"));
            Response.Write("<br />\r\n");

            // 把一些信息写到另外一个文件,借此察看是否正在运行
            string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs");
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);
            DateTime dt = DateTime.Now;
            string shortfileName = string.Format("errors_{0:0000}{1:00}{2:00}.log", dt.Year, dt.Month, dt.Day);
            string fileName = Path.Combine(dir, shortfileName);

            StreamWriter sw;
            if (File.Exists(fileName))
                sw = File.AppendText(fileName);
            else
                sw = File.CreateText(fileName);

            sw.Write(txt.ToString());
            sw.Close();
            sw = null;

        }

 

作了特殊判断的情况简单例子:

注意: IsClientConnected 的判断在 VS.net 开发工具自带的开发站点 ASP.NET Development Server  是不支持的。 ASP.NET Development Server 永远返回 true 。

IIS 才是支持的。

        protected void Page_Load(object sender, EventArgs e)
        {

            StringBuilder txt = new StringBuilder();

            for (int i = 0; i < 100; i++)
            {
                if (this.Response.IsClientConnected)
                {
                    txt.AppendLine();
                    txt.AppendLine(DateTime.Now.ToString("u"));
                    txt.AppendLine(i.ToString());

                    Response.Write(DateTime.Now.ToString("u"));
                    Response.Write("<br />\r\n");
                    Thread.Sleep(500);
                }
                else
                {
                    Response.End();
                    return;
                }
            }

            txt.AppendLine(DateTime.Now.ToString("u"));
            Response.Write(DateTime.Now.ToString("u"));
            Response.Write("<br />\r\n");

            // 把一些信息写到另外一个文件,借此察看是否正在运行
            string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs");
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);
            DateTime dt = DateTime.Now;
            string shortfileName = string.Format("errors_{0:0000}{1:00}{2:00}.log", dt.Year, dt.Month, dt.Day);
            string fileName = Path.Combine(dir, shortfileName);

            StreamWriter sw;
            if (File.Exists(fileName))
                sw = File.AppendText(fileName);
            else
                sw = File.CreateText(fileName);

            sw.Write(txt.ToString());
            sw.Close();
            sw = null;
        }

这个例子中是发现中断,就抛弃之前做的任何东西。

当然我们也可以简单的修改上述代码,让把已经处理完成的东西记录下来,类似下面的代码

        protected void Page_Load(object sender, EventArgs e)
        {
            StringBuilder txt = new StringBuilder();

            for (int i = 0; i < 100; i++)
            {
                if (this.Response.IsClientConnected)
                {
                    txt.AppendLine();
                    txt.AppendLine(DateTime.Now.ToString("u"));
                    txt.Append("**********  ");
                    txt.AppendLine(i.ToString());

                    Response.Write(DateTime.Now.ToString("u"));
                    Response.Write("<br />\r\n");
                    Thread.Sleep(500);
                }
                else
                {
                    break;
                }
            }

            txt.AppendLine(DateTime.Now.ToString("u"));
            Response.Write(DateTime.Now.ToString("u"));
            Response.Write("<br />\r\n");

            // 把一些信息写到另外一个文件,借此察看是否正在运行
            string dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs");
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);
            DateTime dt = DateTime.Now;
            string shortfileName = string.Format("errors_{0:0000}{1:00}{2:00}.log", dt.Year, dt.Month, dt.Day);
            string fileName = Path.Combine(dir, shortfileName);

            StreamWriter sw;
            if (File.Exists(fileName))
                sw = File.AppendText(fileName);
            else
                sw = File.CreateText(fileName);

            sw.Write(txt.ToString());
            sw.Close();
            sw = null;
        }

需要注意的是, 使用 isClientConnected   是要占用一定的系统资源的。

isClientConnected   实际上需要向客户端输出一点东西,然后才知道客户端是否仍然在线。

这样,除非你的应用非常耗时,否则建议你不要用 isClientConnected   。 免得判断 isClientConnected   使用的资源比你实际业务逻辑使用的资源还要多。

在任何情况下, Response.IsClientConnected 都要有些开销,所以,只有在执行至少要用 500 毫秒(如果想维持每秒几十页的吞吐量,这是一个很长的时间了)的操作前才使用它。作为通常的规则,不要在紧密循环的每次迭代中调用它,例如当绘制表中的行,可能每  20 行或每 50 行调用一次。

 

 

参考资料:

how to increase timeout on aspx page?
http://p2p.wrox.com/topic.asp?TOPIC_ID=7504

asp.net能不能在客户端关闭后在后台继续将页面执行完毕?
http://topic.csdn.net/u/20070202/14/85ea5576-907a-4960-9c53-b206a05228e4.html

在 ASP.NET 中使用计时器(Timer)
http://blog.joycode.com/percyboy/articles/3595.aspx

ASP.NET 2.0 中的异步页
http://www.microsoft.com/china/msdn/library/webservices/asp.net/issuesWickedCodetoc.mspx?mfr=true

IsClientConnected的问题
http://topic.csdn.net/u/20080712/19/74fa4070-84bd-4fda-a99b-ac361f874738.html

Response.IsClientConnected 原理和用法
http://blog.51ait.cn/article.asp?id=357    第一个地址比较慢,可以看下一个地址
http://blog.joycode.com/ghj/archive/2008/07/23/115198.aspx

posted @ | Feedback (0) | Filed Under [ .net 编程心得 网站开发管理相关内容 ]

Tuesday, July 22, 2008

 

 

 

       工作九年了,网站相关的开发工作也干了八年多。负责带领团队也好几年了。面试和带领刚工作的人也不少了。其中的优秀者不少,但是大多数都存在下面提到的几个认识误区。把这些问题提出来,希望对刚参加工作没有多久的程序员们有所帮助,少走弯路。

 

      公司招你进来,其实最重要的就是看到你的工作能力和工作态度是可以接受的。

            工作能力指你能满足他们的工作期望,或者在可接受的时间范围内,经过培训后,可以满足这个工作期望。

            工作态度指你能有些做职员的基本素质。

      这个道理应该所有人都清楚。但是到实际事情时候就经常犯迷糊。下面几点是经常会出问题的地方:

 

1、不经测试,Review,就认为自己工作完成了。

       你的代码或者应用一旦被别人Review ,或者进行试用。这时候你代码的好坏,或者功能是否在各种场景下是否可用,都会影响你这个人在上级及同事眼里的可信任度。

       代码书写的规范,性能的高质量,各种功能在各个场景都可用,则表示你这个人是完全可信的。下次上级给你分派任务的时候,就可以给你更多的自由度来发挥。长此以往,前途和钱途自然就随手可得。

        反之,代码不规范,功能好些场景不可用。这只能让上级或同事觉得你不可信任。每次都需要处理你带来的这些问题,说恶心点就是你每次拉完大便都没擦屁股,每次都得你的同事和上级帮你擦屁股。数次都这样后,上级或同事下次跟你沟通的时候就会觉得你这个人不可信任,一件事情必须反复多次强调,总觉得你还会作出问题。你的信用已经非常危险了。

       你在别人眼里的信用就这样被你慢慢透支了。透支到一定程度,走人吧。整个团队的效率会因为你而变慢(每个人跟你沟通的成本都会影响到他本人的产出),你不走人谁走人。

 

2、最短可接受的工作时限

       你有没有统计过,公司分派给你一个工作时候,上级指定的这项工作计划做多久的预计,跟你自己的预计有多大差异?

       如果你预计时间大于上级给的工作计划时间,同时上级没有增派人手进行相关工作。除了BT的领导外,那只有一种情况:上级对你的工作态度非常不满,认为你的薪水对应的工作能力不是这么点。

       对于刚工作的,更多的是你表现出来的工作能力在公司的平均工作能力之下。同时公司觉得你对工作没有表现出足够的热情。 一个能力在平均水平下面,又缺乏工作激情的人,他的前途在那里??

       如果这个人还没有表现出几个月后能达到平均水平之上的希望,为啥会留这样一个人呢?

 

3、工作能力不等于技术水平

       我曾看到过有人抱怨说大公司的员工也不过是这技术水平, 这么简单的技术问题都不会。我自己早期也有这样想法,后来发现是不对的。

       不论大公司还是小公司,要得是解决问题的工作能力。 我的曾经手下就有好几个技术水平很牛的,但是作出来的应用却一次次返工的。为啥,工作能力这些非技术因素他们做的很不好。

       工作能力的非技术因素包括的很多: 责任心,表现就是对自己写出来的代码有一定要让人放心的责任; 沟通能力,一个典型的表现就是需求不理解或者需求不明时,及时得跟相关人沟通,而不是自己先按自己想法实现,造成代码写完后再返工的恶果等等。

       技术水平低,但是解决问题能力强的,我也碰到过一些人。 工作的能力更重要的是这些非技术的工作能力,而不是技术水平。技术人员很容易技术水平高,但是非技术的工作能力差。 这是很糟糕的。

     

 

4、发展潜力,学习能力

      公司使用的技术不可能一直不变,一直不变的公司只能慢慢被市场淘汰。这就要求员工能不断的学习新的知识,并应用到工作中来。

      要想不会出现几年后,自己发现跳槽找个工作都没人要,赶快学习吧。

      坚持,是一个人最难做到的。 但是不坚持,那就等着灭亡吧。

 

 

5、笨鸟先飞

      一个人,在公司,如果工作能力在平均线以下, 加班吧, 不要有任何幻想。

      最可怕的是自己没这个意识, 自认为自己技术水平很牛, 但是解决问题的工作能力却在平均水平线以下, 眼高手低 , 这样的人, 公司是不能留的。

 

 

6、承诺到的事情一定要做到,不要找理由

       一件事情没有被做完,想找理由能找很多的。既然你承诺了某个时间点前完成,就不要再找各种理由推脱。

       公司同事和上级虽然可能这次接受了你的理由,但是下次呢, 慢慢的就会让你的上级,同事觉得你是一个喜欢推托的人。 感觉你干事是非常不可靠的。不知道那次就会不完成,下次谁敢再找你干事?

 

新补充的:

7、有能力者不用加班,能力在平均线之下的自觉加班吧

从CSDN的评论中,争议最大的一个在加班。我这里就补充一下我对加班的看法。

首先,所有人加班,这肯定是领导者的责任, 整体的工作进度压力过大了。

连续的不间断的加班,这也是领导者的责任,人不可能一直处于线绑紧的状态。

但是,如果一个部门,部分人加班,部分人不加班,而且并不是因为领导弱智的把一些人工作分派多,一些人工作分派少导致的。加班的人只能说明他的工作能力在部门的平均线之下。
同一个工作, A 员工干的话 3 天完成, B 员工干的话 5天完成。 最后如果这个工作分派给 B 员工, 很可能是要求他 4天完成。 而且他必须自觉加班。

这就是我所说的 : 有能力者不用加班,能力在平均线之下的自觉加班。

 

 

        可能很多人在看到我这篇博客的时候,觉得我写的很刻薄,好像都是从公司的角度欺压技术人员。很没有人情味。

        只要你不是公司的董事, 你永远是被剥削者,公司的目的就是利润最大化,这是公司存活的根本目的。作为普通的职员,要有所为的白领意识,其实就是被剥削意识。这是个适者生存的生态圈,不适用的人只能被淘汰。

        实际的公司其实有很多人情味在里面,或者同事和领导有些话不便于说出口。 这也就造成了一些技术人员被开除,还自以为如何如何? 都是没有这些意识造成的。我写这篇博客就是希望能增加技术人员的这些意识,不要犯了这些问题还自己不知道。

posted @ | Feedback (5) | Filed Under [ 非技术随笔 网站开发管理相关内容 ]

Wednesday, June 25, 2008

本文概述

StreamWriter 在产生UTF-8编码的内容时候,会在产生的这个UTF-8内容中增加BOM的信息,而这个BOM的信息,会干扰我们在一些情况的使用。
本文描述的情况,就是这种干扰让我们无法正常工作的一种情况。

 

何为BOM?

BOM(Byte Order Mark),BOM签名。
BOM的内容就可以表示unicode文件是何种编码。BOM签名的意思就是告诉编辑器当前文件采用何种编码,方便编辑器识别。

对于UTF-8 , BOM 信息为 EF BB BF。 我们如果在Google搜索 UTF-8 BOM 就会搜索到很多文章, BOM 在不少情况下,都会给我们添乱子。

 

下面是我碰到这个问题的描述

我碰到这个问题的场景:在书写一段模拟HTTP Post 请求的时候, 代码如下,但是却无法模拟Post请求:

private void do2()
 {
     string url = "http://localhost:39749/Default.aspx";



     string indata = "__VIEWSTATE=%2FwEPDwUKMTQ2OTkzNDMyMWRkyGd";
      indata += "iqWjBKr5rIKmHzSdD9AaojKw%3D&Button1=Button&__EVENTVALIDATION=%";
      indata += "2FwEWAgLohfrVDQKM54rGBu49QLoa7JmG9cEfUpTccMrUmJfD";
     HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
     req.ContentType = "application/x-www-form-urlencoded";
     req.Method = "Post";


     Stream myRequestStream = req.GetRequestStream();
     StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.UTF8);
     myStreamWriter.Write(indata);
     myStreamWriter.Close();
     myRequestStream.Close();
     myStreamWriter.Dispose();
     myRequestStream.Dispose();


     HttpWebResponse res = (HttpWebResponse)req.GetResponse();
     StreamReader reader = new StreamReader(res.GetResponseStream(), Encoding.UTF8);
     string info = reader.ReadToEnd();
     reader.Close();
     res.Close();
     reader.Dispose();
     MessageBox.Show(info);
 }

而文中中间的代码修改成下面代码则可以成功模拟。

byte[] bytes = System.Text.Encoding.UTF8.GetBytes(indata);
req.ContentLength = bytes.Length;
Stream myRequestStream = req.GetRequestStream();
myRequestStream.Write(bytes, 0, bytes.Length);
myRequestStream.Close();

为何会这样呢?分析原因,竟然是 UTF-8 BOM 在作怪。

StreamWriter 在产生UTF-8编码的内容时候,会在产生的这个UTF-8内容中增加BOM的信息, 这样他发送的Post信息就比正常多了三个字节  EF BB BF。 就是因为这三个字节导致服务器端无法处理正常的Post请求。

 

解决方法:

1、自己重写UTF-8类,参看 http://www.19870202.com/?tid=381  。在调用的时候用这个自己写的类。
重写代码:
public class UTF8EncodingNoPreamble : System.Text.UTF8Encoding
{
        public override byte[] GetPreamble()
        {
            return new byte[0];
        }
}

2、不要用 StreamWriter ,参看我上面的替代方案。

 

参考资料:

System.IO.StreamWriter写UTF-8文件不写BOM
http://www.19870202.com/?tid=381

UTF-8, UTF-16, UTF-32 & BOM
http://unicode.org/faq/utf_bom.html#BOM

utf-8 保存文件的 bom 问题
http://www.uuzone.com/blog/tom/101761.htm

posted @ | Feedback (0) | Filed Under [ .net 编程心得 技术随笔 网站开发管理相关内容 .net 3.0 .net 3.5 ]

Monday, June 09, 2008

今天在装一台XP的电脑,装完后,第一个就是打得SP3的补丁,这时一切都是正常的。但是装完SP3的补丁后,微软的其他任何一个补丁都装不上去了。比较怪异。

查了很多资料后,发现下面的方法可以解决这个问题,特整理到这里,帮助碰到同样问题的人。

这个解决方法就是在 Windows 中注册 Wups2.dll 文件


要在 Windows 中注册 Wups2.dll 文件,请按照下列步骤操作:
1. 停止自动更新服务。为此,请按照下列步骤操作:
a. 依次单击“开始”和“运行”,键入 cmd,然后单击“确定”。
b. 在命令提示符处,键入以下命令并按 Enter: net stop wuauserv

2. 注册 Wups2.dll 文件。为此,请按照下列步骤操作:
a. 在命令提示符处,键入以下命令并按 Enter: regsvr32 %windir%\system32\wups2.dll
注意:对于运行 Windows XP Professional x64 Edition 的计算机,
请输入以下命令,然后按 Enter: regsvr32 %windir%\syswow64\wups2.dll
b. 在收到的每条验证消息上单击“确定”

3. 启动自动更新服务。
为此,请在命令提示符处键入以下命令,然后按 Enter: net start wuauserv

posted @ | Feedback (0) | Filed Under [ 技术随笔 非技术随笔 ]

Friday, June 06, 2008

我们在使用WEB Service时,需要注意的一点是,传递过程中会丢失一些字符,比较典型的是 /r/n 中 /r 回车字符会被丢弃。这是XML规范所导致的问题。XML规范关于这部分的描述如下:

2.11 行尾处理
为编辑的方便起见,存储XML已析实体的计算机文件经常用行来组织。通常这些行用回车符(#xD)和换行符(#xA)的一些组合来分隔。

为了使应用的工作简单化,对于一个外部已析实体或内部已析实体的常量实体值中包含的任何两字符常量序列"#xD#xA"或单独的常量#xD,XML处理器都应换成#xA传递给应用。(这可以通过在进行语法分析前将所有行分隔符规范成#xA而方便地实现。)

\r   回车(跑到最前面)  
\n  换行(下一行)  

参考资料:

WebServices eat \r in \r\n
http://vidmar.net/weblog/archive/2005/04/03/1203.aspx

XML规范对此相关的解释
http://www.w3.org/TR/2004/REC-xml-20040204/#sec-line-ends
中文版的介绍看下面地址:
http://xml.coverpages.org/xml10-chinese.html#sec-line-ends

\r\n和\r
http://topic.csdn.net/t/20060317/09/4620216.html

Web Service - Carriage Return
http://forums.msdn.microsoft.com/en-US/netfxremoting/thread/bb0ff1f8-0300-4910-be10-6594dff56de4

posted @ | Feedback (3) | Filed Under [ .net 编程心得 技术随笔 网站开发管理相关内容 .net 3.0 .net 3.5 ]

Wednesday, May 07, 2008

我们在应对网站的恶意请求时候,一个解决方法就是把有问题的请求IP封杀掉。

如果想快速处理这种问题,就需要编写一段代码,达到一定门槛,自动封杀。再复杂点就是不是永久封杀,还可以自动在一定时间后解封。

封杀的逻辑代码看后面提供的。

需要说明的是:IIS7时,情况发生了不同。

 

下面的代码,在处理封杀IP时候,不论IIS6还是IIS7 都可以把需要封杀的IP加入封杀列表。但是需要注意的是我们代码写的是全部替换原先的数据。但是在IIS7下,执行的效果是原先的不替换,新加一批封杀IP。当然IIS7下,如果新加的IP原来就有了,则会报如下异常:

System.Runtime.InteropServices.COMException was caught
  Message="当文件已存在时,无法创建该文件。 (异常来自 HRESULT:0x800700B7)"
  Source="System.DirectoryServices"
  ErrorCode=-2147024713
  StackTrace:
       在 System.DirectoryServices.DirectoryEntry.CommitChanges()
       在 IIS_Security_ConsoleApplication.Program.IPDeny() 位置 D:\MyCodes\IIS_Security_ConsoleApplication\IIS_Security_ConsoleApplication\Program.cs:行号 109
  InnerException:

这就是说,IIS7, 我们可以通过编程接口增加封杀IP名单,但是没发通过编程接口剔出封杀IP。

 

参考代码:

这里提供了两套参考代码,其实原理都是一样的。

在IIS 6 下,都没有任何问题, IIS 7 下都会有没发删除原先已有数据的问题。

代码一:


using System.DirectoryServices;
using System.Reflection;
using System;

class Program
{

static void IPDeny()
{

try
{
string serverName = "localhost";
// retrieve the directory entry for the root of the IIS server
System.DirectoryServices.DirectoryEntry IIS = new System.DirectoryServices.DirectoryEntry(
string.Format("IIS://{0}/w3svc/1/root", serverName));

// retrieve the list of currently denied IPs
Console.WriteLine("Retrieving the list of currently denied IPs.");

// get the IPSecurity property
Type typ = IIS.Properties["IPSecurity"][0].GetType();
object IPSecurity = IIS.Properties["IPSecurity"][0];


// retrieve the IPDeny list from the IPSecurity object
Array origIPDenyList = (Array)typ.InvokeMember("IPDeny", BindingFlags.DeclaredOnly | BindingFlags.Public
| BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, IPSecurity, null);

// 罗列已经被拒绝的地址
foreach (