


























最近有个政府项目,客户指定服务器程序必须跑在Linux上面,于是乎我们这帮Linux菜鸟立马开装Linux系统并部署Mono环境。因为对Linux实在不熟的缘故,故在RedHat Enterprise Linux 6中始终没有将MonoDevelop跑起来,于是团队中有同事提议“干脆转Java平台算哒”,哎呦,这么“反动”的想法必须得镇压在萌芽状态。好吧,我承认有些许的个人主观因素作祟,但终究还是需要些冠冕堂皇理由的:
上面晓之以理,下面就该动之以情了,你看这次的Android版的警务通就是用Java来搞的,没有使用那个MonoDroid吧,为啥?因为Mono for Android实在太不成熟了,用它写的程序的无论是体积还是运行效率都没法跟人家比,确实不在一个等级。总而言之,量体裁衣、具体对待。
部门会餐后,俺决定从这个项目组开始逐步进行双机开发,每人配两台电脑,一台装Windows、一台装Linux,在Windows中用VS开发,调试通过后签入SVN中,再在Linux中签出使用MonoDevelop进行一遍单元测试,不用虚拟机,一切原生态同步开发,提升每个开发人员对Linux的熟悉和积累对Mono on Linux的开发经验,于公于私都是非常给力的!
RHEL6中MonoDevelop装不上,咱没功夫跟它耗,赶紧上OpenSUSE和CentOS,这两个都是MonoDevelop官网的主荐平台,果然很给力相当的顺。下面是今天(2011-7-5)将一些后台代码移植到Mono on Linux中的实践札记:
今天移植的两个类库时,只碰到下面两个问题花了一点时间,就运行测试通过了,好爽。
一、在.NET 4.0的System.Type中新增了这个GetType(…)方法重载:
public static Type GetType(string typeName, Func<AssemblyName, Assembly> assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError)
我的代码是这样使用的:
public static Type GetType(string typeFullName)
{
if(string.IsNullOrWhiteSpace(typeFullName))
return null;return Type.GetType(typeFullName, assemblyName =>
{
Assembly assembly = ResolveAssembly(assemblyName);if(assembly == null)
assembly = LoadAssembly(assemblyName);return assembly;
}, null, false);
}
在.NET中一切正常,但是在Mono on Linux中无法正常解析,经查看微软的源码和Mono源码后,发现他们的对于第三个typeResolver参数的处理策略不同,故而将上述代码改成:
public static Type GetType(string typeFullName)
{
if(string.IsNullOrWhiteSpace(typeFullName))
return null;return Type.GetType(typeFullName, assemblyName =>
{
Assembly assembly = ResolveAssembly(assemblyName);if(assembly == null)
assembly = LoadAssembly(assemblyName);return assembly;
}, (assembly, typeName, ignoreCase) =>
{
if(assembly == null)
return null;
else
return assembly.GetType(typeName, false, ignoreCase);
}, false);
}
后来发现对解析像 System.Int32 这样的简写类型名失败,原因就在于typeResolver参数对应的委托回调中传入的assembly参数为空(null),故而将其后的代码(黄色高亮)行改为:return Type.GetType(typeName, false, ignoreCase);即可!
二、在.NET中使用System.Net.HttpListener进行侦听后,如果进程被强制关闭Windows操作系统会回收它所占用的地址和端口(注意:该点未经证实,纯属个人瞎猜),故重新运行该程序后顺利重启HttpListener。但是在Mono on Linux中却行不通,当强制关闭进程后,再次运行会抛出 System.Net.Sockets.SocketException,提示“Address already in use.”这表示Socket已经被占用,需要手动将占用的Socket关闭,那该怎么做呢?首先查出机器中的网络状态,然后找到占用的该Socket的进程,再将该进程Kill掉即可。找到如下操作步骤可解决之:
在Linux终端中,键入这个命令:lsof –i
如果当前用户不是root可能什么也看不到,那么请切换到root用户权限,如:sudo lsof -i
上面命令会提示你输入root根用户的密码,然后即可看到当前机器中的网络占用列表了,这时如果人品没问题的话,应该可以看到cammand为mono的占用记录,如果你清楚自己占用的端口号的话,请这么查看(以88端口为例):lsof –i:88 或者 sudo lsof –i:88
你找到占用程序的进程Id(PID),然后使用kill命令干掉它即可,假设PID为1234:kill 1234 或者 sudo kill 1234
好了,再次运行程序,又跑起来了!Good,先到这,还会有很多问题等着我们的,到时再写吧!
作者:钟峰(Popeye Zhong)目前是 武汉中科通达高新技术有限公司 的软件产品开发负责人,主要负责公司软件产品的技术架构和公共框架开发。他曾经使用 C 语言做过图形程序设计,在相当长的一段时期内从事 COM/COM+ 组件的开发和设计工作,并且短暂的做过 Lotus/Notes 和 Dialogic 语音卡程序的开发,从2003年初开始使用.NET这个充满趣味和挑战的开发平台,还领导过.NET平台下的 Windows Mobile 几个项目的开发,对WinForm和WebForm均比较熟悉。感兴趣的除了企业应用架构设计、组件开发、安全、图像处理外还对汽车和枪械模型、边境牧羊犬有浓厚的兴趣。如果希望与他联系,可访问 http://www.cnblogs.com/sw515 或者Email Zongsoft # gmail.com (将#换成@)。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。