2011年3月31日

一边是招人难,一边是找工作难,这个世界真的很有意思

摘要: 最近有不少公司在狂招人,我也接到了猎头及一些HR公司的电话,希望我能推荐一些人给他们,貌似我都快成专业猎头了。机会满天飞,但实际上发现并无很多合适人员可以推荐。最近发现公司每个职位基本都要耗时几个月之久才能招到合适的人。同时也有很多人找工作,而且发现工作异常难找。这个世界真的很有趣。阅读全文

posted @ 2011-03-31 23:37 ocean 阅读(636) 评论(2) 编辑

2010年5月17日

SharePoint2010-CustomAction中的ContentTypeId属性已经消失了

新的definition如下:

http://msdn.microsoft.com/en-us/library/ms460194.aspx

 

以前的definition没查到,倒是在csdn上查到一篇:

http://blog.csdn.net/forever_kingdom/archive/2008/11/05/3229662.aspx

 

现在如果要指明content type,只要如下即可。

RegistrationId="0x01010100F075B4BFC1A01E47B6D99B358E050F49"
RegistrationType="ContentType"

其中RegistrationId写ContentTypeId即可。

 

如何获得ContentTypeId?最简单的方法就是鼠标放到Content Type上,然后地址栏中就会显示出一个link,link中就包含ContentTypeId。

 

如果你想给某个文档库或者列表单独添加一些Custom Action,比如菜单,或者Ribbon,那么最好的方法就是让这些文档库或者列表实现一个特殊的Content Type。

 

以后估计会写一些Blog,不过我不会再写SharePoint入门了,我会列出我所发现的一些MOSS2010和MOSS2007有差异的地方。

posted @ 2010-05-17 18:46 ocean 阅读(964) 评论(3) 编辑

2010年4月23日

office2010和sharepoint2010可以下载了?

刚刚看了一下msdn订阅,意外发现已经可以下载了,更新时间是4月22日。有msdn订阅账号的可以一睹为先了。

 

posted @ 2010-04-23 16:19 ocean 阅读(1970) 评论(8) 编辑

2010年4月21日

一个子目录里放100W个文件及SQL Server File Stream中放100W文件,会怎么样?

      如果我有100W个小文件,每个接近100K,然后我要放到一个目录里面,NTFS的子目录是否能够承受住单个目录存放100W的文件?如果采用sql server 2008的File Stream功能呢?我们知道SQL Server 2008启用了Filestream的字段的表,是一个字段放到一个子目录,如果我100W条记录都放在一个表里面,对应磁盘上仍然是1个子目录会有100W个文件。那结果会怎样?

      在很多流言中,有一些认为一个子目录存放超过10W的文件会产生不稳定的情况,通常在遇到这种场景,都直接建议采用分级目录存放,包括我们在一个表里面插入100W条记录。但是windows ntfs和sql server真的有这么差吗?当然不会,我们知道sql server 2008即使管理100T数据也没有问题。而网上最广泛的流言之一就是Oracle的性能比sql server的性能好,这个流言是在sql server 2000的时候产生的,那个时候是事实,但是sql server 2005已经改变了这一状况,而sql server 2008则彻底颠覆了这种情况,但是,流言,仍然继续的流传了下来(看看最新的TPC-E排名:http://www.tpc.org/tpce/results/tpce_perf_results.asp ,TPC-E可是比TPC-C的更新的基准测试哦)。还有一个著名的流言就是SharePoint列表中不要存放超过2000条记录,否则将引起性能的严重下降,这个流言在SharePoint 2003的时候是属实的,但是在SharePoint 2007里面就已经改善了,流言也仍然传了下来。

      首先说一下今天要讨论的场景,既然要在sql server 2008里面存放100W个文件,那么显然这是一个服务端应用,而不是一个客户端应用,因为没有人会手动的从100W个文件中去挑选什么。我的 测试环境如下:

      OS: Windows Server 2008 R2

      硬盘: SATA 日立 1T 7200转

      CPU:双核 2G

      数据库: SQL Server 2008 Enterprise(MSDN license)

      可用内存:足够大(不会出产生内存不足而导致的额外硬盘交换,占用IO的情况)

  测试文件大小:90K,也即将插入90K的文件100W份,相当于将这个文件复制了100W份。

      真正的服务器一般采用SCSI高速硬盘,所以IO状态会比我的测试机器好很多,而这台机器是我的开发用机,在1T的硬盘上还有3个虚机在同时运行,所以相对而言IO是比较差的。如果在我这台机器上能够承受的住,我相信在真正的服务器上都不会有任何问题。

      测试代码:      

代码
 1 static void Main(string[] args)
 2         {
 3             SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=NorthPole;Integrated Security=SSPI;");
 4             conn.Open();
 5             SqlCommand cmd = new SqlCommand();
 6             cmd.Connection = conn;
 7             cmd.CommandText = "AddFile";
 8             cmd.CommandType = System.Data.CommandType.StoredProcedure;
 9 
10             DateTime begin = DateTime.Now;
11             for (int i = 1; i < 100001; i++)
12             {
13                 cmd.ExecuteNonQuery();
14                 Console.WriteLine("{0} rows are inserted!", i);
15             }
16             DateTime end = DateTime.Now;
17             conn.Close();
18 
19             TimeSpan t = end - begin;
20             Console.WriteLine("{0} Days, {1} Hours, {2} Minutes, {3} Seconds", t.Days, t.Hours, t.Minutes, t.Seconds);
21             Console.ReadLine();
22         }
23 

 

里面的AddFile是存储过程:

 

代码
ALTER PROCEDURE [dbo].[AddFile] 
AS
BEGIN
    
-- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    
DECLARE @img AS VARBINARY(MAX)


-- Load the image data

SELECT @img = CAST(bulkcolumn AS VARBINARY(MAX))

      
FROM OPENROWSET(

            
BULK

            
'D:\temp\test.jpg',

            SINGLE_BLOB ) 
AS x

            

-- Insert the data to the table           

INSERT INTO Items (ItemID, ItemImage)

SELECT NEWID(), @img
END

 

 

我首先插入了10W条记录到数据库中,执行结果如下:

 

由于我担心Console.WriteLinei++这两句代码耗费时间过多,所以做了一下时间补偿,将cmd.ExecuteNonQuery()注释掉,然后做10W次空循环,结果如下:

基本不会对结果产生什么影响。

效率:总共:3757秒,0.03757/

然后我将循环改成了90W次,往数据库插入90W条记录,执行结果如下:

时间补偿:

效率:总共:52674秒, 0.0585/条。

 随着记录数的增多,显然速度会变慢,不过这点效率损失基本还能够忍受。

 虽然对应的目录里面存放了100W的记录,但是目录还是能够打开,不过windows文件管理器的响应速度会变慢,当然这个主要原因应该是widnows文件管理器的原因,毕竟100W条数据不是一个小数字。我们能够看到这个目录有100W项目。

 

通过sql语句:

SELECT TOP 1000 [ItemID]

      ,[ItemImage]

  FROM [NorthPole].[dbo].[Items]

 

取前1000行记录,大约用时16秒。

很明显,sql server 具有很好的缓存功能,当我再次执行这条语句的时候,仅仅用时6秒。

随后我执行了几次,基本都维持在67秒的样子。

在取任何一条记录的时候,时间都是0秒。我这里感觉不到速度的差异。

关于如何使用SQL Server File Stream功能,这里有一篇blog写的非常详细:http://www.simple-talk.com/sql/learn-sql-server/an-introduction-to-sql-server-filestream/

从我个人的感觉来说,基本没有什么问题,而且如果换成专门的服务器,采用快速的SCSI硬盘,效率应该比我现在的测试结果要好上很多。

 

当然上述结果仅供参考,如果你需要采用的话,建议在你的真实环境里面再实际测试一遍。毕竟不同的环境,可能得到的结果不相同。

 

 附加,额外的:

 

 

posted @ 2010-04-21 14:18 ocean 阅读(2070) 评论(40) 编辑

2010年3月5日

Prism2.0之自定义ModuleCatalog(for Silverlight)

      今天比较高兴,因为网站的备案终于被审核通过了,我的网站很早之前就备过案,但是很奇怪两个月之前备案信息莫名其妙就消失了,结果在上次大检查中被迫关闭,重新备案路漫漫,经过两个月马拉松式的备案,今天备案信息终于通过,网站重新开通(http://www.oceanstudio.net/ ), 比较汗颜了,我的网站也没有更新什么东西。

      趁着高兴,写篇Blog吧,主要在于太长时间没写Blog了,现在也不知道写什么好,恰巧前段时间碰到有人问我,在Prism中,可否把模块信息放到xml文件中。这个自然没有问题,我们做一个自己的ModuleCatalog就好,不过我一直没有做,今天正好简单实现了一下,有兴趣的朋友可以参考。

  为什么要分模块,这个当然有很多好处,比如独立开发、独立测试,独立加载,而且模块之间没有直接引用,修改之后不会引起其他模块产生问题,总归好处多多。当我们做一个小型的Silverlight程序时,可以不用考虑Prism,直接做就好了,但是如果你做一个RIA,比如business application,那么可能会有上百个页面,不同的数据、表格等等,如果不分模块,那最后肯定就乱成一锅粥了。架构就是为了让我们的项目更加有条理,并且在变的越来越复杂时能够更好的控制,还能随时适应变化的要求。

      Prism2.0中,本身可以把模块的配置信息放置到XAML中,在自带的smaple中,我们可以看到如下代码:

 

 1 <Modularity:ModuleCatalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 2                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 3                 xmlns:sys="clr-namespace:System;assembly=mscorlib"
 4                xmlns:Modularity="clr-namespace:Microsoft.Practices.Composite.Modularity;assembly=Microsoft.Practices.Composite">
 5     <Modularity:ModuleInfoGroup Ref="ModuleX.xap" InitializationMode="OnDemand">
 6         <Modularity:ModuleInfo ModuleName="ModuleX" ModuleType="ModuleX.ModuleX, ModuleX, Version=1.0.0.0" />
 7     </Modularity:ModuleInfoGroup>
 8     <Modularity:ModuleInfoGroup Ref="ModulesWY.xap" InitializationMode="WhenAvailable">
 9         <Modularity:ModuleInfo ModuleName="ModuleY" ModuleType="ModuleY.ModuleY, ModulesWY, Version=1.0.0.0">
10             <Modularity:ModuleInfo.DependsOn>
11                 <sys:String>ModuleW</sys:String>
12             </Modularity:ModuleInfo.DependsOn>
13         </Modularity:ModuleInfo>
14         <Modularity:ModuleInfo ModuleName="ModuleW" ModuleType="ModuleW.ModuleW, ModulesWY, Version=1.0.0.0">
15         </Modularity:ModuleInfo>
16     </Modularity:ModuleInfoGroup>
17     <!-- Module info without a group -->
18     <Modularity:ModuleInfo Ref="ModuleZ.xap" ModuleName="ModuleZ" ModuleType="ModuleZ.ModuleZ, ModuleZ, Version=1.0.0.0" />
19 </Modularity:ModuleCatalog>

 

 

     在Bootstrapper中,我们就可以如下调用:

 

代码
        protected override IModuleCatalog GetModuleCatalog()
        {
            
return
                ModuleCatalog.CreateFromXaml(
                    
new Uri("/RemoteModuleLoading;component/ModulesCatalog.xaml", UriKind.Relative));
        }

 

 如果我们要放在XML中,也很简单,声明如下的这么一个文件:

 

代码
<?xml version="1.0" encoding="utf-8" ?>
<Modules>
  
<Module name="LeftMenuModule" mode="WhenAvailable" type="SilverlightMonitorApplication.LeftMenuModule.LeftMenuModule, SilverlightMonitorApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  
<Module name="BottomMenuModule" mode="OnDemand" type="SilverlightMonitorApplication.BottomMenuModule.BottomMenuModule, SilverlightMonitorApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    
<Module.DependsOn>
      
<ModuleName>LeftMenuModule</ModuleName>
      
<ModuleName>Module1</ModuleName>
    
</Module.DependsOn>
  
</Module>
  
<Module name="Module1" mode="OnDemand" type="SilverlightMonitorApplication.Module1.Module1, SilverlightMonitorApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
  
</Module>
  
<Module name="Module2" mode="OnDemand" type="SilverlightMonitorApplication.Module2.Module2, SilverlightMonitorApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
  
</Module>
</Modules>

 

 

然后自己实现一个ModuleCatalog,我这里就命名为XmlModuleCatalog,这个XmlModuleCatalog当然要从ModuleCatalog继承下来。当然你也可以有更好的实现方式。我就提供个思路就好,代码我随手写的,论写代码,我是赶不上专职开发人员了。

 

代码
    public class XmlModuleCatalog : ModuleCatalog
    {
        
public XmlModuleCatalog(string xmlUri)
            : 
base()
        {
            
try
            {
                XElement doc 
= XElement.Load(xmlUri);

                var q 
= from x in doc.Descendants("Module")
                        select 
new ModuleInfo(x.Attribute("name").Value, x.Attribute("type").Value, (from c in x.Descendants("ModuleName")
                                                                                                     select c.Value).ToArray()
                                              ) { InitializationMode 
= x.Attribute("mode").Value.Equals("OnDemand"? InitializationMode.OnDemand : InitializationMode.WhenAvailable };

                
foreach (ModuleInfo m in q)
                {
                    
this.AddModule(m);
                }
            }
            
catch
            {
                
throw new ArgumentException("XML file is not found or invalid!");
            }
        }
    }

 

 

      然后就可以在bootstrapper里面轻易调用

 

代码
        protected override IModuleCatalog  GetModuleCatalog()
        {
            
try
            {
                return
 new XmlModuleCatalog("ModuleInfo.xml");
            }
            
catch
            {
                
return null;
            }
        }

 

 

这里注意几点:

  1. XML文件的BuildAction为Content,不需要当做资源编译到dll中。
  2. 我没有去考虑每个模块在不同xap里面的情况,因为这种情况直接用xaml来描述就好了,没必要再自己重新做。
  3. Depends的问题,只要放在ModuleName里面就好了,我并没有去管ModuleName是否放在<Module.DependsOn>里面,当然主要是图省事。
  4. 我使用LINQ来实现的,这样比较省事一点,大家也可以用其它的方式来读取XML。

     这里说下模块按需下载的问题,如果模块需要按需下载,直接用XAML的形式就好了,这个Prism里面是自带的,不过考虑一般项目的模块不是特别多,而每个模块不是特别大,经常每个模块几十K,100多K,所以都打包在一起更加方便。当然如果模块过多或者过大,还是应该采用按需下载的方式比较好。

 

     在Prism中,模块的加载过程和那一大堆class啊,interface啊之间的关系,可以从下面两个图中来了解:

 

     上面两个图取自Prism的帮助文档中。 

 

      当然其实我定义这个xml文件,最初的初衷是想把module的view信息定义进去,让view也能根据配置文件动态加载。这个XmlModuleCatalog应该说是一个附属品。

 

      祝大家Happy.

 

posted @ 2010-03-05 17:59 ocean 阅读(988) 评论(2) 编辑

2008年11月10日

Teched2008 DEV301 ADO.NET Data Service资料下载

posted @ 2008-11-10 18:03 ocean 阅读(2107) 评论(11) 编辑

2008年10月28日

Teched 2008课程:ADO.NET Data Service & UC开发概览

posted @ 2008-10-28 21:37 ocean 阅读(1614) 评论(8) 编辑

2008年10月15日

我的基于Silverlight2的相册,也刚刚升级到了RTW了。

posted @ 2008-10-15 03:35 ocean 阅读(383) 评论(2) 编辑

2008年9月14日

很囧,请大家不要给我留言

posted @ 2008-09-14 16:35 ocean 阅读(515) 评论(2) 编辑

2008年8月1日

在MOSS中给增强型RTF字段增加按钮

posted @ 2008-08-01 22:29 ocean 阅读(1770) 评论(6) 编辑