适合C# Actor的消息执行方式(6):协变与逆变
2010-09-30 20:50:09 来源:WEB开发网public class Parent
{
public void ParentMethod() { };
}
public class Child : Parent { }
static void Main(string[] args)
{
IPort<Child> childPort = new ChildPortType();
IPort<Parent> parentPort = childPort; // 自动转化
parentPort.Post(p => p.ParentMethod()); // 可以接受Action<Parent>类型作为消息
}
这意味着,我们可以把ICrawlRequestHandler和ICrawlResponseHandler类型写成下面的形式:
internal interface ICrawlRequestHandler
{
void Crawl(IPort<ICrawlResponseHandler> collector, string url);
}
internal interface ICrawlResponseHandler
{
void Succeeded(IPort<ICrawlRequestHandler> crawler, string url, string content, List<string> links);
void Failed(IPort<ICrawlRequestHandler> crawler, string url, Exception ex);
}
如今,Monitor和Crawler便可以写成如下模样:
internal class Crawler : Actor<Action<Crawler>>, IPort<Crawler>, ICrawlRequestHandler
{
protected override void Receive(Action<Crawler> message) { message(this); }
#region ICrawlRequestHandler Members
void ICrawlRequestHandler.Crawl(IPort<ICrawlResponseHandler> collector, string url)
{
try
{
string content = new WebClient().DownloadString(url);
var matches = Regex.Matches(content, @"href=""(http://[^""]+)""").Cast<Match>();
var links = matches.Select(m => m.Groups[1].Value).Distinct().ToList();
collector.Post(m => m.Succeeded(this, url, content, links));
}
catch (Exception ex)
{
collector.Post(m => m.Failed(this, url, ex));
}
}
#endregion
}
public class Monitor : Actor<Action<Monitor>>, IPort<Monitor>, ICrawlResponseHandler
{
protected override void Receive(Action<Monitor> message) { message(this); }
#region ICrawlResponseHandler Members
void ICrawlResponseHandler.Succeeded(...) { ... }
void ICrawlResponseHandler.Failed(...) { ... }
#endregion
private void DispatchCrawlingTasks(IPort<ICrawlRequestHandler> reusableCrawler)
{
if (this.m_readyToCrawl.Count <= 0)
{
this.WorkingCrawlerCount--;
}
var url = this.m_readyToCrawl.Dequeue();
reusableCrawler.Post(c => c.Crawl(this, url));
while (this.m_readyToCrawl.Count > 0 &&
this.WorkingCrawlerCount < this.MaxCrawlerCount)
{
var newUrl = this.m_readyToCrawl.Dequeue();
IPort<ICrawlRequestHandler> crawler = new Crawler();
crawler.Post(c => c.Crawl(this, newUrl));
this.WorkingCrawlerCount++;
}
}
}
- ››适合做商品团购营销的网站
- ››适合所有浏览器hack的CSS技巧
- ››消息称中国移动即将获得iPhone 4销售权
- ››适合C# Actor的消息执行方式(1):Erlang中的模式...
- ››适合C# Actor的消息执行方式(2):C# Actor的尴尬...
- ››适合C# Actor的消息执行方式(3):中看不中用的解...
- ››适合C# Actor的消息执行方式(4):阶段性总结
- ››适合C# Actor的消息执行方式(5):一个简单的网络...
- ››适合C# Actor的消息执行方式(6):协变与逆变
- ››适合1-5个月经验的seo优化全过程分享
- ››消息称联通高层赴美谈引入iPhone4 将带WiFi
- ››消息称微软将在近期发布IE9 beta
更多精彩
赞助商链接