02

用Remoting实现进程间通信,真的很简单、很好用。
服务器端(exe)控制端(web)都是用.net写的,原本两者的通信想用Socket,毕竟我写了一个还蛮好用的网络库(自我陶醉~~),但真的被协议所累,即使用序列化传输,也是要处理一大坨东西,偷偷懒,采用Remoting,为一不爽的地方是以前的设计是单线程,不用加锁,现在要在服务器端的主循环进行加锁,而且也不好控制控制端大量访问造成的压力,但需求决定,这个控制端不会有好多人用,所以是可行的。

在决定采用这个方案后决定对Remoting进行一个简单的封装,目的是为了减少使用者的学习负担,也为了减少上层代码对这种机制的依赖(说不定哪天发现不符合需求就换掉!)
一、定义Server被web的基本操作的接口,我们定为IServerControl,里面只有一个Add方法。 Continue reading »

23

这一段时间一直在写C#代码,虽然我是个超爱C/C++的人,吼吼!C/C++里面经常写一些宏,来简化重复代码,虽然不被提倡了,但我还很喜欢,也许我很变态!

1、在.net设计规范一书中(P128),在调用委托前除了要加一个非空测试之外,还要加一个防止竞态条件的保护,综合书上做法,我用这种办法简化。

    public static class EventHelper<teventargs> where TEventArgs : EventArgs
    {
        //警告	8	CA1030 
        public static void Raise(EventHandler<teventargs> hander, object sender, TEventArgs args)
        {
            //.net设计规范 P128
            EventHandler<teventargs> eventHander = hander;
            if (eventHander != null)
            {
                eventHander(sender, args);
            }
        }       
    }

2、深拷贝一个对象,一般系统默认提供的是返回一个浅表副本,自己为每一个类写一个深拷贝又显得冗余,反正都是用序列化实现,不如偷偷懒

对于继承于同一接口的函数,一般都会用工厂来创建对象,他们可能有这相同的构造函数,也可以稍微统一以下
Continue reading »

16

需求:
客户端,服务端通信协议采用Xml格式。
因为客户端采用非.net语言写,有一些自己的约定,所以不能直接使用xml序列化。

不想为每一个协议写一个ToXml和ParseXml的函数,懒得维护,也容易出bug,决定用反射自己写一个,大部分的基本类型都很好处理,直接用XmlWriter.WriteValue()和XmlReader.ReadElementContentAs()就可以,问题来了,自己写的类怎么办?KeyValuePair<,>怎么办?

我想用两种办法解决这个问题:
1、加Attribute,不含有标签的直接采用XmlReader/XmlWriter的方法,含有标签的采用自定义的做法

Continue reading »

13

策略模式定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。

Windows的计划任务的时间触发器设计的非常合理,是一个通用触发器模型,可以完成时间触发的大部分需求,所以参照Windows时间触发器写一个具有时间触发的模块是一个不错的选择。taskschd

共有四种类型的触发器,一次,每天,每周,每月,高级设置是这四种触发器公用的,主要包含了重复、过期、是否启用,于是可以这样设计

Continue reading »

02

ADO.NET2.0 为各种ADO.NET类引入了一个提供程序工厂的模型以及通用基类。
1、ADO.NET通用接口的限制:
接口不易扩展
ADO.NET1.1无法创建某些类的实例
ADO.NET1.1无法判断可用的.NET数据提供程序。
2、提供工厂模型如何解决上述限制
通过抽象积累来扩展ADO,NET模型
使用DbProviderFactory类来创建对象
3、提供程序工厂模型的限制
许多查询结构都是数据库特有的
为参数化查询设置CommandText时,可能需要提供程序特有的代码
指定参数数据类型可能需要提供程序特有的代码

为了使开发的代码通用,不局限于特定的数据库,本次开发中决定使用DbProviderFactory+标准SQL,以开发一个适用于mysql和sqlserver的封装,但DbProviderFactories 并没有提供对mysql的DbProviderFactory的支持,所以需要扩充DbProviderFactories类兼容mysql,而且在ADO.net 2.0中mysql和sqlserver的ParameterMarkerFormat都有bug,所以扩展类要解决这个bug

Continue reading »

22

C++不是运行时类型(RTTI),虽然可以使用dynamic_cast来动态转化,但因为效率问题,也没有几个人用。

问题可以这样问:如何判断两个对象是不是同一类型,或者如何判断一个对象是不是某种类型?

前一段看gTest的源代码,发现了一个有趣的做法

Continue reading »

10

最近在做网站,发现收费空间速度不错,但空间容量有限,拿来存储图片、音乐等太浪费了,而且这些内容对网速的要求不高,最好把这些图片放在国外免费空间,问题来了,国外免费空间虽然稳定,但经常被墙,怎么办?

用相对路径来存储图片,比如说我在论坛发图,地址是http://www.886s.com/forum/app/downloadbase.php?q=comic%2FOnePiece%2F1%2F1.jpg
而真实地址是在国外的一个免费空间上,在http://www.886s.com/forum/app/downloadbase.php页面上做个重定向就可以实现。万一这个免费空间被墙了,我可以把这些图片存到其他的免费空间上,并且修改一下downloadbase.php就可以。

downloadbase.php源代码如下:

Continue reading »

02

教训:仔细分析小问题有时可以带来巨大的实际好处!

经典算法:位图法

1.6

1、采用 set,边读边排序.

2、不经常使用。

因为我经常认为采用 移位 取代 乘法、除法,用 交& 取代 取模(取余),不能真正地提高效率(编程精粹 专门说过这个问题),但现在发现我没有设计好。(在记忆里,我曾经在一个论坛的设计中,采用了 移位算法 来表示用户在一个论坛中的权限,这个机制仿效的是MFC中的设计。 唉!大学时代!!)

3、程序 ProgrammingPearls-01-01

4、程序 ProgrammingPearls-01-02

关于此程序,我想采用BITMAP对于重复的在随即一次,而给的例程是申请一个大数组,进行交换,对于10,000,000中选1,000,000例程的速度比我得快接近3倍,空间多占用20倍

Continue reading »