【发布时间】:2012-02-16 09:37:23
【问题描述】:
我的 lightswitch 应用程序中有一个函数,可以从我想使用 Rx 框架重写的站点下载 csv 文件,并提供同步调用它的可能性。
下面提供旧功能和新功能的代码sn-ps。然而,新功能不起作用,对 ParseCSV 的调用永远不会发生。我想知道为什么以及是否存在更好的解决方案,请随时提供。
旧代码:
private void ObservableCollection<Data> collection;
public ObservableCollection<Data> GetData(string url, ObservableCollection<Data> targetCollection)
{
collection = targetCollection;
if (!string.IsNullOrEmpty(url))
{
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(OpenReadCompleted_ParseCSV);
wc.OpenReadAsync(new Uri(url));
}
return collection;
}
private void OpenReadCompleted_ParseCSV(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error != null) return;
var webClient = sender as WebClient;
if (webClient == null) return;
try
{
using (StreamReader reader = new StreamReader(e.Result))
{
string contents = reader.ReadToEnd();
...
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Error parsing CSV!\n" + ex.Message);
}
}
新代码(带 Rx):
private void ObservableCollection<Data> collection;
public ObservableCollection<Data> GetData(string url, ObservableCollection<Data> targetCollection)
{
collection = targetCollection;
if (!string.IsNullOrEmpty(url))
{
var result = Observable.FromEventPattern<OpenReadCompletedEventHandler, OpenReadCompletedEventArgs>
(
ev => webClient.OpenReadCompleted += ev,
ev => webClient.OpenReadCompleted -= ev
)
.Select(o => o.EventArgs.Result)
.FirstOrDefault()
.ParseCSV();
// Call the Async method
webClient.OpenReadAsync(new Uri(url));
}
return collection;
}
private void ParseCSV(this Stream stream)
{
try
{
using (StreamReader reader = new StreamReader(e.Result))
{
string contents = reader.ReadToEnd();
...
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Unable to get history data!\n" + ex.Message);
}
}
【问题讨论】:
-
只是一个快速提示 - 你在滥用 Rx - 这一切都应该在一个没有
FirstOrDefault的查询中完成... -
这是我第一次尝试使调用同步(来自 Functional Alchemy 的想法:使 Silverlight 同步)
-
Rx 就是异步的。如果您尝试使其同步,您很可能会遇到死锁。您使用“LinqPad”工具吗?如果没有,你应该下载它。非常适合在“便签本”环境中尝试 Rx 代码。
-
它声明“Rx 是一个库,用于使用可观察序列和 LINQ 样式的查询运算符组合异步和基于事件的程序”。我正在使用 Rx 将我的事件作为可观察的集合进行访问,因此利用了我们今天拥有的 Linq 优势。
标签: .net csv webclient system.reactive