【发布时间】:2011-08-01 03:26:46
【问题描述】:
最近读F#,原来是“异步”和“!” (砰!:p)是非常有用的功能。 (题外话,这是一个例子,说明编程语言不仅是一个学术研究课题,而且是一个现实生活中的生产力设计课题。
以下内容来自 Luca Bolognese 的 PDC 2008 演示文稿:
let internal loadPrices ticker = async {
let url = "http://ichart.finance.yahoo.com/table.csv?s=" + ticker + "&d=9&e=30&f=2008&g=d&a=2&b=13&c=1986&ignore=.csv"
let req = WebRequest.Create(url)
let! resp = req.AsyncGetResponse() //athos: need F# Powerpack
let stream = resp.GetResponseStream()
let reader = new StreamReader(stream)
let! csv = reader.AsyncReadToEnd()
let prices =
csv.Split([|'\n'|])
|> Seq.skip 1
|> Seq.map (fun line -> line.Split([|','|]))
|> Seq.filter (fun values -> values |> Seq.length = 7)
|> Seq.map (fun values ->
System.DateTime.Parse(values.[0]),
float values.[6])
return prices }
迷人之处在于,回调被优雅地处理:程序员不需要处理 BackgroundWorker 或 Theads 的 Join()。
那么,在 C# 中,是否有一个优雅的解决方案来实现 F#“aync”和“!”特征? 例如,是否可以像下面这样或以类似的轻松方式执行“async...run...callback”?
public void GetApplicationSettings()
{
async(objAsyncRunner = new System.Async.Runner() ) //similar to "using" in C#
run // similar to "if" in C#
{
string url = "http://ichart.finance.yahoo.com/table.csv?s=" + ticker + "&d=9&e=30&f=2008&g=d&a=2&b=13&c=1986&ignore=.csv"
var req = WebRequest.Create(url);
var resp = req.AsyncGetResponse();
}
callback run // similar to "if else" in C#
{
var stream = resp.GetResponseStream();
var reader = new StreamReader(stream);
var csv = reader.AsyncReadToEnd();
}
callback // similar to "else" in C#
{
var prices = csv.Split('\n').....;
}
}
ps。我知道有些人会说:athos,就用 F#! 是的……我不反对F#,但整个部门都需要时间来改变,在此之前我希望能借鉴F#的一些优点。
我知道有一些 Aspect 编程概念可以扩展 C# 功能。但是还没有达到F#级别。
例如,我可以从 http://www.sharpcrafters.com 扩展 PostSharp,以便通过简单地将属性分配给方法,强制它在专用线程中异步运行:
[RunInADedicatedThread(Async = true)]
public void GetApplicationSettings()
{ ... }
如果属性已准备好:
[Serializable]
[AttributeUsage( AttributeTargets.Method | AttributeTargets.Class )]
[MulticastAttributeUsage( MulticastTargets.Method )]
public sealed class RunInADedicatedThreadAttribute : MethodInterceptionAspect
// MethodInterceptionAspect is extending PostSharp
{
public bool Async { get; set; }
public override void OnInvoke( MethodInterceptionArgs args )
{
if (Async)
{
//MyThreadPool is my extention for PostSharp
MyThreadPool.GetThread().ExecuteAsync(
() =>
{
args.Proceed();
} );
return;
}
MyThreadPool.GetThread().Execute( args.Proceed );
}
}
这有点帮助,但仍然不是 F# 级别:
- “在专用线程中异步运行”请求不是在调用中定义的,而是在 GetApplicationSettings() 方法本身上定义的!这个方法还不如改名为GetApplicationSettingsAsynchronously(),不是吗;
- 还有,这不能帮助回调部分;
- 更不用说使用更少线程的 F#“异步”功能了……我什至可以暂时放弃这个“高级”功能……
【问题讨论】:
-
简化 C# 中的异步编码...
-
athos:我想你会对C# & .NET 5.0感兴趣
-
@Alastair : 谢谢,让我消化一下。我想知道 C# 什么时候发布?
-
有一个 CTP 可用于测试,我猜测完整版本是明年某个时候。
标签: c# asynchronous f# callback aop