posts - 59,  comments - 36,  trackbacks - 11
  2011年4月19日
回顾工作这五六年来,自己有哪些地方进步了,又有哪些成就,该好好想想,作下总结的时候了,先列出四点供思考吧。
1、怎么给职业定位,职业规划该是怎么样?
2、这些年的.NET开发我到底沉淀了些什么,我有些什么优势,我的不足又有哪些呢?
3、对技术的认识,我目前停留在表面、熟练、还是有深层次的理解呢?
4、我是否已经摸索出了一套成熟,有效的工作、学习方法?
posted @ 2011-04-19 00:33 EasyWriter 阅读(52) 评论(0) 编辑
  2008年12月4日
摘要: 目录1.1 log4net的简要说明,在具体项目中扮演的功能角色。1.2 Log4net 组成结构说明1.3 Log4net配置文件解析1.4 举一个实际的例子,阐述Log4net的完整的实现流程1.1 log4net的简要说明,在具体项目中扮演的功能角色。Log4net 是一个第三方开源组件,它设计的主要目的是组合,生成日志信息,同时将配置保存到各种存储介质或者展现平台中,在实际项目中,Log4...阅读全文
posted @ 2008-12-04 17:53 EasyWriter 阅读(159) 评论(0) 编辑
摘要: 现在每个程序员都会说:OO思想,OO开发,呵呵,是真的理解了嘛?看看下面的文章就知道啦。。。面向对象的开发方法(Object Oriented,OO) 从事软件开发的工程师们常常有这样的体会:在软件开发过程中,使用者会不断地提出各种更改要求,即使在软件投入使用后,也常常需要对其做出修改,在用结构化开发的程序中,这种修改往往是很困难的,而且还会因为计划或考虑不周,不但旧错误没有得到彻底改正,又引入了...阅读全文
posted @ 2008-12-04 17:48 EasyWriter 阅读(233) 评论(1) 编辑
  2008年8月21日

转载,文章来源:http://blog.csdn.net/akunshenjk/archive/2008/03/28/2226040.aspx

 

     早在一年前我就曾接触到Lucene.net 当时版本为1.9.1 .004 ;当时学习该框架时,正赶上它宣布进去商业化,可能不会再出更高版本了;后来不知道什么原因,又重新开源,并出了新版本(2.0.0.004),也是一年前的事了。刚接触Lucene,net的目的是改善网站的搜索,提高搜索效率。由于lucene是有java开源框架迁移过来的,所以相关资料大多是java的文档,相关文档基本是英文,所以当时学习的时候是比较吃力的。最后经过两个星期的奋斗,总算是把lucenet.net的脾性摸清楚了,并且做出来了相应的程序。可是,用了不多一个星期,发现写的程序并没有提升搜索效率,很是失望;同事决定弃用lucenet.net,换用其它方式。

          最近网站的数据量越来越大,搜索的效率再次成了大问题。于是又回到Lucene.net上,这次当然要用新版本(2.0.0.004),结果其与1.9.1.004版本有一些差别。先将这次学习经验盘点如下:

一.创建索引:IndexWriter 

     其构造函数:

 

public IndexWriter(   string path,   Analyzer a,   bool create);
public IndexWriter(   FileInfo path,   Analyzer a,   bool create);
public IndexWriter(   Directory d,   Analyzer a,   bool create);

 

我们常用的是第一个构造函数。string path 为索引所在目录,如:D:\search\index; Analyzer a是选用词语分析器;如 new StandardAnalyzer();最后一个参数是表示是否需要重新创建,如果是初次创建索引,则用true,否则一般为false。

所以创建索引可以按如下写:创建新的文档:
Document doc = new Document();

 

 //索引已存在,则直接打开 否则创建,并打开
//this.m_strIndexPath 为索引目录
IndexWriter m_writer =new IndexWriter(this.m_strIndexPath, new Lucene.Net.Analysis.Standard.StandardAnalyzer(), !System.IO.File.Exists( System.IO.Path.Combine(this.m_strIndexPath, "segments")));

 

二.创建文档(Lucene.Net.Documents)
构造函数:

 

public Document();

 

 

主要方法有:
Add() 增加索引
Get() 获取索引字段存储的值
GetBoost() 获取权重
SetBoost() 设置权重
GetField() 返回赋予字段的名
RemoveField() 从文档中删除特定名的字段

三.字段(域)Fields
构造函数:

 

public Field(   string name,   byte[] value_Renamed,   Store store);
public Field(   string name,   TextReader reader);
public Field(   string name,   TextReader reader,   TermVector termVector);
public Field(   string name,   string value_Renamed,   Store store,   Index index);
public Field(   string name,   string value_Renamed,   Store store,   Index index,   TermVector termVector);

 

string name 为字段名, string value_Renamed 字段对应的值,Store 对应有YES 和NO,YES则存储对应值,否则不存储;Field.Index对应有四个值,这对我们创建索引以及优化有很大的帮助.
NO 不把字段值编入索引,因此该字段不会被搜索到
NO_NORMS 不使用分析器将字段值编入索引,不会按规范存储,它的优点是占用空间少
TOKENIZED 将字段值编入索引,并可以被搜索到,在这个规则被存储在索引之前,有一个分析会被用用来标志这个正文,或者可能的话,使这个正文更加正规化,这对于普通文本是非常有用的。
UN_TOKENIZED 不使用分析器将字段值编入索引,因此它可以被搜索到, 没有使用分析器,值将被存储为单独的项目,这对唯一的ID是非常有用的,比如产品数量

四.搜索(示例)

 

System.DateTime dt = System.DateTime.Now;
IndexSearcher searcher 
= new IndexSearcher(@"d:searchprovide");
string q=Keyword.Text;
Query query1 
= QueryParser.Parse(q, "P_Name"new StandardAnalyzer());
Hits hits
=searcher.Search(query1);
TimeSpan ts 
= System.DateTime.Now.Subtract(dt);
string results = ts.TotalMilliseconds.ToString() + "毫秒;Found " + hits.Length() + " document(s) that matched query '" + q + "':<br/>";
int count=hits.Length();
if(count>30)count=30;
for (int i = 0; i < count; i++
{
     Document doc 
= hits.Doc(i);
     results
+=doc.Get("HtmlPath")+"<br/>";
     results
+=doc.Get("ID")+"<br/>";
}

Label1.Text
=results;            
searcher.Close();

 

五,高亮显示查询结果

在Lucene.net2.0里有插件 Highlighter.Net,引入该插件,我们可以是搜索结果高亮显示。

示例:

 

using Lucene.Net.Highlight;//引入
//其它代码省略
 QueryParser q = new QueryParser("P_Name", analyzer);
  Query query1 
= q.Parse(Request["bizKeyword"]);
 query.Add(query1, BooleanClause.Occur.MUST);
  Lucene.Net.Highlight.Formatter fm 
= new SimpleHTMLFormatter("<span style="color:red;font-weight:bold">""</span>");
  highlighter 
= new Highlighter(fm, new QueryScorer(query1));
  highlighter.SetTextFragmenter(
new SimpleFragmenter(100));

//中间代码省略

//高亮显示
 string P_Name = doc.Get("P_Name");
  Lucene.Net.Analysis.TokenStream tokenStream 
= analyzer.TokenStream("P_Name"new System.IO.StringReader(P_Name));
  P_Name 
= highlighter.GetBestFragments(tokenStream, P_Name, 0"...");
                               
            

 

六.索引的实时更新(伪)
         Lucene.net是非常好用的一个开源搜索框架,但是很可惜它不支持读写并发操作。搜索的时候不能更新索引,更新索引的时候不能进行搜索。这对于数据经常要更新的场景,真可谓是致命的。
        在java下有人说:利用compass,hibernate实现lucene索引实时更新。我没试过,相应的资料也没找到。
再说了据我所知,目前Compass还每有从Java迁移到.net,至于hibernate有.net版的 Nhibernate ,不过据说效率很成问题。
        为了解决这问题,我想了很多办法。最后我的解决办法很土,不过我认为还是很好用的。现将我的方法结束如下:
       比如我们要对产品进行建立索引,首先建议一份完整的索引,保存的目录A,再复制一份保存到目录B,A目录的主要作用就是在正常情况下提供搜索的索引目录,B目录则主要用于更新新的索引(包括删除废旧数据,修改,新增数据);一旦更新操作完成,立即通知搜索更换目录到B目录,让删除A里的旧索引,并复制B里的最新索引到A目录。 

这里之所以加一个“伪”字,我这里实现并不是实际意义的实时,这里还是有一定时间差的,因为Lucene.net优化索引比较耗时,我不可能每插入一条数据,就更新索引;我的做法是每间隔一段时间,待修改数据达到一定量时,再一起操作,更新索引,优化。这样也减少了很多I/O操作。

-------------------------------------------------

PS:今天搜索到一篇文章:http://blog.csdn.net/poson/archive/2008/03/21/2201880.aspx

里面简单的说了Lucenet.net的并发操作,如果其正确,那么我的文章里所说的“。搜索的时候不能更新索引,更新索引的时候不能进行搜索”则是错误。尽管如此,但有一点是肯定的:更新索引会耗用大量cpu资源。

posted @ 2008-08-21 03:16 EasyWriter 阅读(681) 评论(0) 编辑
  2008年7月5日
原文:http://www.codeproject.com/KB/dotnet/ADONET_ConnectionPooling.aspx

1:合并数据库连接

   与数据库服务器建立连接是非常消耗系统资源的,如果某个系统需要查询某个数据库服务那么必须首先建立起与该数据库的连接然后再执行查询。
   你是否能够感觉到当您在客户端使用相同的查询向服务器提交查询信息的时候结果的返回会越来越快。从服务器端将数据返回数据到客户端有一种机制产生了以上的结果,而这种机制就是在ADO之间建立连接
   我们通常是把与数据库连接的信息存储在配置文件中,利用它在系统中频繁地打开与关闭与数据库的连接。这样我们不管是访问多大或多小的数据我们都是用的一样的连接。
   IIS中的ADO.NET有一种叫做连接池的技术是解决以上问题很好的方法。当应用程序第一次发生请求的时候建立与数据库的请求而当系统关闭数据库连接的时候。ADO.NET没有完全的销毁连接,而是把这个连接对象放到连接池中并保留对他的引用。当下一次发生请求的时候ADO.NET从连接池中调出连接运用到本次查询中。这样可以提高一定的效率。

2:创建连接池

   连接池和连接字符串是紧密联系的。一个连接池有进程,应用程序域以及连接字符串来确定的。(process,domain ,connection string
   当我们利用ADO.NET向数据库发送查询的时候,在相同的进程和应用程序域中ADO.NET利用确定的连接字符串匹配连接池中的连接对象。如果找到并且该连接空闲可用那么就得到该连接用于本次请求,否则就建立新的连接并把该连接添加到连接池中。在向连接池添加连接的时候不能超过连接池最大连接数量。
   我们可以利用Close() or Dispose()方法在利用后立即销毁连接二而不是等到GC来释放连接消耗的资源。

3:删除和清理连接池

   当应用程序被卸载的时候连接池也随之销毁。在我们的ASP.NET系统中连接池在第一次请求的时候建立当重启IIS的时候销毁。连接池依赖于我们的IIS而不是我们的开发环境。因此你不能通过关闭DEV来销毁连接池。
   在ADO2.0中新增了两个清理连接池的方法
ClearAllPools,ClearPool

4:通过连接字符串来控制连接池

   下表列出连接字符串中有关连接池设置的选项
  
 Name  Default  Description
 Connection Lifetime  0  

When a connection is returned to the pool, its creation time is compared with the current time, and the connection is destroyed if that time span (in seconds) exceeds the value specified by Connection Lifetime.

A value of zero (0) causes pooled connections to have the maximum connection timeout.

 Connection Timeout  15  Maximum Time (in Secs) to wait for a free connection from the tool
 Enlist  'true'  

When true, the pooler automatically enlists the connection in the creation thread's current transaction context. Recognized values are true, false, yes, and no.

Set Enlist = "false" to ensure that connection is not context specific.

 Max Pool Size  100  The maximum number of connections allowed in the pool.
 Min Pool Size  0  The minimum number of connections allowed in the pool.
 Pooling  'true'  When true, the SQLConnection object is drawn from the appropriate pool, or if it is required, is created and added to the appropriate pool. Recognized values are true, false, yes, and no.
 Incr Pool Size  5  Controls the number of connections that are established when all the connections are used.
 Decr Pool Size  1  Controls the number of connections that are closed when an excessive amount of established connections are unused.

    除了注意以上列表以外还有一个需要注意的。我们在连接字符串中尽量利用USERID,PQSSWORD来建立连接,这样一个客户可以利用其他客户建立的连接。否则则会为每个客户建立连接。

5:一个连接字符串的例子

    initial catalog=Northwind; Data Source=localhost; Connection Timeout=30; User Id=MYUSER; Password=PASSWORD; Min Pool Size=20; Max Pool Size=200; Incr Pool Size=10; Decr Pool Size=5;

6:查看用ADO.NET建立的连接池

    在MS SQLSERVER中,打开查询分析器执行EXEC SP_WHO
    在ORACLE中,打开类似PL/SQL的客户端工具执行
SELECT * FROM V$SESSION WHERE PROGRAM IS NOT NULL
   

7:连接池中常见的异常

    Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached
    问题描述:我们获取连接超过连接池最大值时产生如上异常。通常连接池最大值为100。当我们获取连接超过最大值时,ADO.NET等待连接池返回连接而超时,这样将抛出如上异常
    解决办法:首先要做的是在我们使用连接后立即关闭连接。如果没有关闭连接那么连接将保存到连接池中知道GC来销毁。这种情况下你以为连接池没有到达最大值但实际上连接池已经到达了最大值
                  其次我们可以通过连接字符串中的
Max Pool Size = N;来动态扩大连接池中的连接最大数量。
                  在者就是关闭连接池
   
A transport-level error has occurred when sending the request to the server. (provider: Shared Memory Provider, error: 0 - Shared Memory Provider: )
    问题描述:ADO.NET以为数据库存在某一确定连接但是数据库由于重启而丢失了所有连接。
    解决办法:对于ORACLE如果你用ODP,NET访问数据库那么你应该在连接字符串里加上
Validate Connection=truevalidcon=true
                 
对于对于MS SQLSERVER,你可以用SqlConnection.ClearPool静态方法清除连接池。该方法在SqlClient,OracleClient 中都有。
                  对于.net1.1下的MS SQLSERVER
                        a:重建连接池销毁无用连接池
                        b:捕获异常循环刷新连接直到ADO.
posted @ 2008-07-05 10:52 EasyWriter 阅读(436) 评论(0) 编辑
  2008年6月17日
打开网页时,提示“internet explore 无法打开internet站点...,已终止操作”,
曾以为是application 的原因,百思不得其解
今天晚上找遍了google、baidu、sogou,还是一无所获
看原页面代码,查找是否 DIV 没有结束,又不是。最后只能判断是JS 的问题了。
不错,正是js引发的错误。
由于页面中用到了下拉条,而且,微软把 select 的属性值设得太高了,层是没办法把他遮挡住的。只能用错就错在 <iframe 这里了,页面还没完成,就跑 <iframe ,<iframe 还没引发完成就跳转,导致游览器中断,所以就出现了 “internet explore 无法打开internet站点...,已终止操作”,
如下就是网页中用到的js,
function openShim(menu,menuItem)
{
   if (menu==null) return;
    var shim = getShim(menu);
    if (shim==null) shim = createMenuShim(menu,getShimId(menu));
----------------------------------------------------------------------------------------
只要稍微修改为以下就可以了
function openShim(menu,menuItem)
{
if (document.readyState!="complete") return ;  
  if (menu==null) return;
    var shim = getShim(menu);
    if (shim==null) shim = createMenuShim(menu,getShimId(menu));
。。。。
即加上一个载入判断就可以了。 if (document.readyState!="complete") return ;
“internet explore 无法打开internet站点...,已终止操作”,从此消失
另:遮掩 select 的方法还可以用如下:
var allselect = document.getElementsByTagName("select");
for (var i=0; i {
  allselect[i].style.visibility = "none";
}
或者用window.onload=function(){}
也是可以的


文章来源:http://www.cnblogs.com/xin478/archive/2007/07/27/833129.html
posted @ 2008-06-17 00:39 EasyWriter 阅读(3837) 评论(0) 编辑
  2008年5月20日
摘要: 很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解。比如:select * from table1 where name='zhangsan' and tID > 10000 和执行:select * from table1 where tID > 10000 and name='zhangsan'  一些人不知道以上两...阅读全文
posted @ 2008-05-20 00:54 EasyWriter 阅读(179) 评论(0) 编辑
摘要: 随着“金盾工程”建设的逐步深入和公安信息化的高速发展,公安计算机应用系统被广泛应用在各警种、各部门。与此同时,应用系统体系的核心、系统数据的存放地――数据库也随着实际应用而急剧膨胀,一些大规模的系统,如人口系统的数据甚至超过了1000万条,可谓海量。那么,如何实现快速地从这些超大容量的数据库中提取数据(查询)、分析、统计以及提取数据后进行数据分页已成为各地系统管理员和数据库...阅读全文
posted @ 2008-05-20 00:53 EasyWriter 阅读(151) 评论(1) 编辑
  2008年5月13日
摘要: 转贴一位老兄的文章,懒得细看,先收藏备用。CREATE PROCEDURE dbo.UspOutputData @tablename sysname AS declare @column varchar(1000) declare @columndata varchar(1000) declare @sql varchar(4000) declare @xtype tinyin...阅读全文
posted @ 2008-05-13 22:36 EasyWriter 阅读(224) 评论(0) 编辑
  2008年5月10日
摘要: 1.static方法是类中的一个成员方法,属于整个类,即使不用创建任何对象也可以直接调用!static内部只能出现static变量和其他static方法!而且static方法中还不能使用this....等关键字..因为它是属于整个类!2.静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁。3.静态方法和静态变量创建后始终使用同一块内存,而使用实例的方式会创建多个内存...阅读全文
posted @ 2008-05-10 01:20 EasyWriter 阅读(1153) 评论(1) 编辑