【原文地址】ASP.NET MVC Talk in Reading UK July 3rd
【原文发表日期】 Thursday, July 02, 2009 1:11 AM
今明两天我将在英国,我是在从这个星期两天的印度之行的回国途中,准备在此做2个技术讲座。
第一个讲座将在今晚的伦敦用户组织的活动上,我将讲演Silverlight 3。不幸的是,这个活动的注册已经超员了,所以,如果你还没有注册的话,等下次我来时再光临吧。
第二个讲座将在明天(星期五)从下午1点-4点在瑞丁(Reading)的微软设施举行,是关于ASP.NET MVC的。上个星期刚宣布该活动不久,它的注册很快就超员了。但这个星期,感谢我们的主办人,他们找到了一个大一点的房间,所以又多出了120个座位。
如果想参加的话,你可以在今天下午4点前注册参与这个免费讲座。但要快哟,因为只剩下43个座位了(在我刚开始撰写这个博客贴子时还有57个座位)。
希望在那里看到你们,
Scott
最近在做多线程处理数据库的程序时,这个程序总是会报如下错误:
超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。
System.Data
在 System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
在 System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
在 System.Data.SqlClient.SqlConnection.Open()
仔细用 SQL Server Management Studio 中的 Activity Monitor 查看数据库链接,竟然是只有2,3个数据库链接时,就报上述错误,很是怪异。
一步步删除掉代码,反复试验后,竟然是数据库链接字符串中的 Connect Timeout=0 来作怪的。
比如下述数据库链接字符串就会出现上述问题,
Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=DB1;server=(local);Connect Timeout=0
而把数据库链接字符串修改为
Persist Security Info=False;Integrated Security=SSPI;Initial Catalog=DB1;server=(local)
就不会有问题了。
这个bug在微软的反馈中可以看到,如下:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=331882&wa=wsignin1.0
其中微软的官方反馈是:
The fix was submitted to the source branch of the next major .Net release.
由 Microsoft 在 2008/8/15 11:31 发送
照这么说,估计.net 4.0 中会修复这个bug。
参考资料:
Why Does a Connection Pool Overflow?
http://msdn.microsoft.com/en-us/library/aa175863%28SQL.80%29.aspx
Trace a SqlConnection - Connection Pooling issues
http://www.experts-exchange.com/Software/Server_Software/Web_Servers/Q_22589733.html
Fixing connection pooling timeout exceptions on third-party code
http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=14
Connection Pooling and the "Timeout expired" exception FAQ
http://blogs.msdn.com/angelsb/archive/2004/08/25/220333.aspx
ADO.NET Connection Pooling at a Glance
http://blog.csdn.net/tuwen/archive/2008/05/28/2490299.aspx
FIX: Sp_reset_connection Does Not Reset the Rowcount Settings for the DELETE and UPDATE Statements
http://support.microsoft.com/kb/310617/ ADO.NET数据连接池
http://tech.it168.com/db/s/2006-10-18/200610181013413.shtml
关于ADO.Net连接池(Connection Pool)的一些个人见解
http://www.cnblogs.com/rickie/archive/2004/10/02/48546.aspx
How to: Open Activity Monitor (SQL Server Management Studio)
http://msdn.microsoft.com/en-us/library/ms175518.aspx
Connect Timeout = 0 / Connection Pool Timeout
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=331882&wa=wsignin1.0
最近正好有个朋友问这个方面的问题,如何规划一个SharePoint系统的磁盘容量?如果不能在前期做系统规划(Planning)的时候,确定好所需的磁盘容量,那么就很可能遇到系统上线3个月之后,发现服务器磁盘不够用的尴尬情况发生。
在微软TechNet网站上,有一些相关的文档和白皮书,比如《Capacity Planning and Sizing for Microsoft SharePoint Products and Technologies》。但是如果你懒得阅读白皮书,那么我可以给出一些简要的参数,根据这些参数,你可以快速的估算出一个SharePoint系统所需要的大致磁盘容量。
1、首先,你需要估算出整个系统中将要存放的内容的总容量。如果整个系统的总容量会随着系统的运行而不断增加(很多时候确实如此),那么你就想想你希望整个系统在上线后多长时间之内不想再进行磁盘容量上的升级,然后估算出这段时间之内,系统所存放的内容的总容量。
比如,每个月,所有用户会上传大概10GB文档到SharePoint服务器上。如果你希望SharePoint系统在未来两年之内,不用考虑容量升级的问题,那么这两年内,SharePoint系统中将存放总共240GB的文档。
由于SharePoint 2007文档管理会有“版本控制”和“回收站”的功能,所以在你估算的时候,不要忘记估算这两个功能将要占用的磁盘容量。
比如,在整个系统中,如果你估算大概会有5%的文件会存放到启用了版本控制功能的文档库中(提示:通常,并非所有文件都会需要版本控制的功能,很多文件都是一次性完成,或是无需保留历史版本的,对于这个文件所在的文档库,应该谨慎的使用版本控制功能),并且通过文档库的设置,限制了最多只保留10个主要版本,每个主要版本最多只保留5个次要版本(提示:对于启用了文档版本的文档库,同样需要设置好最多的主要版本的次要版本,避免版本数量无谓的增加太多),那么对于上面算出的240GB文档,你就需要还要加上240GB * 5% * 10 * 5 = 600GB的容量。
这样,我们计算出来的总容量空间将是:240GB + 600 GB = 840GB。
2、由于SharePoint会将所有的网站内容都存储到SQL Server数据库中,对于整个系统的数据库,你要准备所有内容总容量再乘上1.2-1.5倍的空间,给到SQL Server数据库。
比如,对于在第一个步骤里面计算出来的内容总容量840GB,我们就要给SQL Server数据库准备840GB * 1.5 = 1.3TB的磁盘空间。
3、由于SharePoint里面的索引服务(Index Services)会为所有的内容创建索引文件,所以你还需要注意为索引文件准备足够的磁盘空间。索引文件会占用的磁盘空间,可以按照(内容总容量 * (5-12%)) * 3倍这个公式进行计算。
对于5-12%这个比例,需要按照SharePonit中所存储的内容类型来进行适当的调整。例如,对于文档类型的内容(.doc、.docx、.xls、.xlsx、.pdf等),索引文件所占用空间的比例肯定会要比图片文件要高。如果你的SharePoint系统中主要是存放文档类别的内容,那么你就要将这个比例适当的加大,也就是更接近12%。
比如,对于840GB的内容,如果这些只有一部分是文档类型,那么我们要为索引文件准备840GB * 8% * 3 = 200GB的空间。
注意,如果在你的SharePoint服务器场中,索引服务是运行在一台单独的索引服务器(Index Server)上,那么就要在索引服务器上准备这么大的磁盘空间。
4、如果在SharePoint服务器场中,查询服务(Query Services)不是与索引服务运行在同一台服务器上,由于SharePoint会自动将索引文件从索引服务器上复制到运行查询服务的服务器上,所以在所有运行了查询服务的服务器上,同样需要准备足够的磁盘空间,留给索引文件。要准备的磁盘空间容量,计算方法与索引文件的容量相同。
5、最后,为了防止在估算的时候过于乐观,而且你也有足够的预算,那么不妨将上面的所有计算结果再乘上1.5 - 3倍(倍数可以按照您手里的预算来决定,呵呵)。比如,为SQL Server数据库准备2TB的磁盘空间,为索引文件准备300GB的磁盘空间。
最后,介绍两个SharePoint容量规划工具。第一个是微软的SharePoint Capacity Planning Tool,这个工具依赖于System Center Capacity Planner 2007。根据我的使用经验,个人认为这个工具过于花哨,实用价值不太高。:)
第二个工具是HP ProLiant Sizer for Microsoft Office SharePoint Server 2007,它是HP公司发布的一个工具。我对此工具没有什么使用经验。
3月份从Windows Live转到Windows Embedded后,越来越多地需要与C/C++相依为命了。以前在C#里写点字符串处理的东西基本不用动什么脑子,现在单单是把两个字符串连起来,就要调用一个有4个参数的API。
最近在做的一个项目顶层的用户界面(UI, User Interface)还是选择用C#/WinForm写了,毕竟再用MFC之类的东西,身心受不了那个摧残。不过底层真正实现功能的API还是必须要用C/C++来写(有很多客观的原因必须如此),所以一个必然需要解决的问题就是如何让用托管代码写成的UI层来调用用非托管代码写成的API层里的函数/类。也不知这样的事大家现在是否还经常需要做,不知会用COM/ATL的还有多少人,不过既然就此做了一些调查,我想还是把结果整理一下,写下来,也许对一些朋友会有用呢。
本文只讨论如何从托管代码调用非托管代码,其实反向操作(非托管代码调用托管代码)也有很多类似的技术,大家可以自己查一下资料。
基本上从托管代码调用非托管代码的函数/类型有一下几类方法:
1. 通过Platform Invoke (P/Invoke)
这个在托管代码需要调用Windows API的时候是很常见的,比如要调用kernel32.dll里的SetDllDirectory这个native API,只要这样做就可以了:
using System.Runtime.Interopservices
public MyClass
{
[DllImport("kernel32.dll", SetLastError=true)]
static extern bool SetDllDirectory(string lpPathName);
...
public static void CallSetDllDirectory(string path)
{
...
SetDllDirectory(path);
...
}
}
利用P/Invoke最大的麻烦可能就在于这个native函数的P/Invoke的签名应该如何申明。最常见的一种方法叫做google,就是你把TheAPIYouWantToCall和P/Invoke这两个关键字放在一起google一把,基本就应该找到了,第一个连接十有八九是来自www.pinvoke.net这个网站。
不过如果你要是说你不喜欢Google怎么办?Google上找不到怎么办?要是Google当掉了怎么办?要是Google因为传播色情信息被封锁了怎么办?当然你可以说:我没有Google我有Bing,那也是可行的。不过其实还有更直接的方法,在2008年1月的MSDN杂志上的CLR Inside Out的专栏里就有这么一篇文章:Marshaling between Managed and Unmanaged Code,其中介绍了P/Invoke Interop Assistant这个工具。你不但可以通过这个工具来查找绝大多数公开的Windows API的P/Invoke的签名,而且也可以用它来产生你自己写的native API的P/Invoke签名,很方便。你可以在这里下载这个工具。
2. 通过C++/CLI wrapper class
这个方法主要是利用Managed C++来写一个封装函数/类,并以此来调用非托管的函数/类,而在另一边,用Managed C++写成的封装类的dll又可以直接被C#等托管代码来调用。
假设你有如下的C++类:
class __declspec(dllexport) NativeClass
{
public:
static void Func(LPTCSTR);
...
};
你可以在Visual Studio中建立一个Visual C++的CLR空项目:
记得调整配置的类型:
然后编写如下的Managed C++类:
public ref class MCppClass
{
public:
static void Func(String^ str)
{
NativeClass::Func((LPTSTR)Marshal::StringToHGlobalUni(str).ToPointer());
}
...
};
编译后生成的dll就可以直接被托管代码调用了。当然,关于托管代码变量和非托管代码变量之间marshaling的问题也是很头疼的,不过这个不是本文的讨论内容。
3. 通过CALLI instruction以及Reflection.Emit直接调用非托管代码
CALLI是Intermediate Language (IL)的一个指令。老实说我也不太清楚这个东东怎么用,只是看有的文章提到说可以如此做,但没有深入地研究一下,有兴趣的同学可以参考一下David Broman的这篇文章。
4. 通过COM interop
这个就留待明天的Part II再讲吧,因为我还想顺带提一下COM里的一些相关内容,篇幅可能有些长,并且时间也不早了…
【原文地址】Writing A Page To A String
【原文发表日期】 May 29, 2009
ASP.NET页面通常是将它们内容直接输出到一个请求响应流(response stream)中。这对比较大型的页面来说应该是一个巨大的效率优化,因为这样做就不需要为页面显示而建立很大的缓冲区或者分配很大的字符串。而分配大型字符串的操作经常会在“大型对象堆栈”(Large Object Heap)上获取所需的内存,而这也意味着这些内存块不会被很快地资源回收。
然而,很多情况下你可能确实需要将一个页面的内容输出到一个字符串里以便进行一些后处理工作。关于这点,我N久之前也曾经写过一篇blog介绍了一个方法:就是使用response filter。
不过,最近我学到了Page类中的一个我从没有注意到过的方法,这个方法提供了以上问题的一个更轻量级的解决方案。
我所说的就是CreateHtmlTextWriter这个方法,它是一个保护(protected)成员函数的,而且也是一个虚(virtual)函数的。
以下是一个页面code-behind的代码示例,其中利用了这个函数来对页面的输出内容进行过滤,经此处理后的内容才最终显示在浏览器中。
public partial class FilterDemo : System.Web.UI.Page
{
HtmlTextWriter _oldWriter = null;
StringWriter _stringWriter = new StringWriter();
protected override HtmlTextWriter CreateHtmlTextWriter(TextWriter tw)
{
_oldWriter = base.CreateHtmlTextWriter(tw);
return base.CreateHtmlTextWriter(_stringWriter);
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
string html = _stringWriter.ToString();
html = html.Replace("REPLACE ME!", "IT WAS REPLACED!");
_oldWriter.Write(html);
}
}
在CreateHtmlTextWriter方法中,我们首先是调用基类的该函数来创建一个原来的HtmlTextWriter,然后将它暂时存放在一个成员变量中。
然后我们还是调用基类的函数来创建一个新的HtmlTextWriter,不过这个对象实例会使用我们自己的StringWrtier作为底层的TextWriter。被传入到Render函数中的HtmlTextWriter就是这个新创建的实例。(在Render函数中)我们首先对这个新的HtmlTextWriter实例调用基类的方法,然后将底层StringWriter的输出内容取出,这样就可以对该部分内容进行所需的处理了。我们最后将最终的输出内容写到原先的HtmlTextWriter中去,因为原先的这个HtmlTextWriter是真正负责将结果写到请求响应中去的。
使用这个技巧的时候有很多值得特别注意的地方。首先,如我先前所提到的,对于大型的页面,以上所做的这些事可能会大大地影响你网页的运行效率和可伸缩性。而且,我也没有针对输出缓存、异步页面等等的情况下测试过上面的技巧,所以你很可能会遇到意想不到的实际结果。
注意,如果你是需要从一个页面调用另一个页面,然后在第一个页面中得到后者的输出内容,那么你可以将你自己的TextWriter实例传到Server.Execute函数中并得到结果,所以这种情况下你无需借助上面所介绍的这个技巧。
Scott等就ASP.NET MVC 1.0编写了Professional ASP.NET MVC 1.0一书,并提供了免费的第一章、第二章下载。其中,第一章以一个完整的案例NerdDinner讲解了如何使用ASP.NET MVC技术对网站进行开发。这个一篇指导意义非常强的教程,对于ASP.NET MVC的初学者是最合适不过的教学案例了。第一章提供了html版和PDF版,EntLIb论坛对 这些内容进行了翻译,提供了比较完整的HTML中文版。HTML网页固然方便,但毕竟过于零散,不如PDF文档显得正式和统一。此外,EntLib对 Scott的案例作了少量的修改,增加了EntLib的标识。同时,该网站还省略了教程中集成地图的部分,我觉得略有遗憾。所以,我在EntLib的基础 上,完善了整个文档的翻译,还原了英文版的本来面目,并提供了PDF格式的文档。
内容包括:
1、创建MVC Web Application
2、创建数据库
3、创建Model模型
4、控制器和视图
5、创建、更新、删除记录
6、模型绑定的安全性
7、ViewData和ViewModel
8、Partials和Master页面
9、认证和授权
10、AJAX实现RSVP响应
11、集成AJAX地图
12、单元测试
13、依赖注入
完整文档下载:ASP.NET MVC Step by Step中文版
博客堂源代码自从去年开始就一直紧跟ASP.NET MVC的进度,开发了很长时间,一直都不好意思拿出来给大家显白显白。主要原因是Bug太多,实在是拿不出手。但在开发过程当中,实在是需要听取大家的反馈意见,所以现在把相关的工作做了一下整理,先把0.5的第一个CTP发布出来,以听到相关的建议。目前博客堂还运行的是0.4版本,所以像BING的搜索在博客堂上还没有出现,取而代之的是Google的BlogBar功能(不过Google的BlogBar对页面加载还会有一定的阻碍的)。
如果您希望下载源代码,请确保您的开发环境与我一样(其它环境主要是我个人没有进行过测试,希望各位有测试结果可以通知一下)。
1. IDE: Visual Studio 2008 SP1;
2. .NET Framework Version: 3.5 SP1;
3. ASP.NET MVC: 1.0;
4. OS: Windows 7 RC/Windows Vista/Windows Server; (ASP.NET MVC在IIS6下运行还需要特殊配置);
5. SQL Server 2008: 2005应该也可以,但我没有做过测试。
点击此处查看或者下载源代码;点击此处下载安装文件(不含源文件)
目前版本尚有很多Bug,不推荐普通用户下载。非常感谢。
[原文发表地址] Microsoft BizSpark: Serving 15,000 startups and counting!
[原文发表时间] Friday, June 19, 2009 11:15 PM
8个月之前,微软对外公布了Microsoft BizSpark的项目。这个项目旨在帮助创业初期的公司,通过提供免首付的微软软件、技术支持,以及可视度获得成功。
今天,我很高兴地宣布,迄今为止,已经有15000多个创业公司加入了BizSpark的项目。
参与的公司获得功能完整的微软平台及开发工具,比如Windows Server,SQL Server,Visual Studio和Expression Studio。BizSpark在99个国家中实施,并不要求独家经营权。许多开源的独立软件开发商正利用BizSpark测试他们应用程序的互通性,或是增加他们所能支持的客户端平台数量。
这15000个参与的公司所参与创新的领域包括社群网络,软件服务,保健,教育,移动,娱乐,以及财经。这些创业公司正在Windows的平台上成功的构建着他们的应用程序。他们的名字包括:ZocDoc,Tweba,SquareClock,Eduify,StackOverflow,Sobees,MixedInKey,Develomatic。
这里有一些最近加入BizSpark项目的富有创新精神的公司。

在2008年12月看过Microsoft Surface之后,Nicolas Chaillan激起了灵感,想创造after-mouse,为Windows7和Surface构建可定制的触觉用户体验。After-mouse使用WPF和Silverlight,为在欧洲及其它地区的旅行社,零售商,房产商和医院构建多点接触的用户体验。BizSpark的产品许可证让after-mouse可以使用微软的技术创建宿主解决方案。
下图中,after-mouse的酒吧和餐馆应用程序可以让客人直接在餐桌上为晚餐点单。


Curse是一家坐落于硅谷的大型多玩家在线游戏或MMO的门户社区。该网站为MMO游戏提供论坛、wiki、评论、下载、博客、录像以及其他资源。Curse的重点在于游戏玩家生成的内容,并允许玩家创建他们自己的页面。Curse包含了World of WarCraft,StarCraft和Age of Conan的门户网站。
现在Curse已经拥有了140多万用户,并且此数目还在快速增长中。他们的网站使用了三台IIS7的web服务器和一个运行SQL Server 2008的数据库服务器。Curse的桌面客户端从.NET web服务中获得数据。该.NET web服务用C#编写,并运行在两台IIS7 web服务器上。Curse的CEO曾说:“我们的成功大部分归功于微软技术的性能和稳定性,以及使用微软开发工具所提供的生产力。我们将继续依然只使用微软的技术。我们正在使用WPF开发下一代的Curse客户端版本,并用ASP.NET MVC构建公共宿主服务。”

Lokad,一个由5人组成,创建于2007年的法国创业公司,向零售业、制造业,和呼叫中心行业提供在线业务预测和统计数据。将你的历史数据,如销售、现金流、呼叫数量、客户要求等,发送给Lokad,他们会把预测结果发送给你。Lokad的数学家团队使零售公司可以用最少的投资使用到顶尖水平运作的业务预测。Lokad的网络应用程序使用的是.NET 3.5,并使用LINQ技术和SQL Server中的数据进行交互。除此之外,Lokad是第一个在他们的产品开发环境中使用Windows Azure服务的独立软件供应商。
看到这些创业公司使用微软的平台和工具进行创新的工作着实令人兴奋。
欲了解更多关于BizSpark,以及如何加入的信息,请访问BizSpark on Startup Zone。
Namaste!
今天很怪异,我的PowerPoint出现了下面的提示对话框后,不论我选择是或者否,我的PowerPoint都再也打不开了。
网上搜索了相关资料,通过下面步骤删除这个插件后,就可以正常使用了。
- 单击开始→运行→输入Powerpnt.exe /safe回车,尝试以安全模式运行POWERPOINT。
- 如果可以运行,点击POWERPOINT选项→加载项→里面的活动应用程序加载项→去除对应插件。
参考资料:
启用或禁用 Office 程序中的加载项
http://office.microsoft.com/zh-cn/help/HA100341272052.aspx
http://bbs.kafan.cn/thread-459528-2-9.html
在WS-*标准和规范中,WS-Discovery是在2008年才加入了OASIS标准。WS-Discovery在标准被定义为Web Service Dynamic Discovery,其目的是为定位服务定义Discovery协议,主要应用在为客户端动态搜索一个或多个目标服务。OASIS为WS- Discovery提供了两种操作模式:ad hoc和managed模式。
ad hoc模式根据类型在托管目标服务的范围内查找目标服务。客户端会以多播的形式发送一个Probe(探测)消息,如果服务匹配该信息,则以单播方式直接将响应发送到客户端。为了能够根据名称定位目标服务,客户端会以相同的多播组发送一个Resolve(解析)消息,同样的,匹配该消息的服务会直接以单播方式响应客户端。消息交换的流程如下图所示:
全文阅读>>