- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的解决方案中有两个项目:WPF 项目和类库。
在我的类库中:
我有一个符号列表:
class Symbol
{
Identifier Identifier {get;set;}
List<Quote> HistoricalQuotes {get;set;}
List<Financial> HistoricalFinancials {get;set;}
}
public async Task<IEnumerable<Symbol>> GetSymbolsAsync()
{
var historicalFinancialTask = new List<Task<HistoricalFinancialResult>>();
foreach (var symbol in await _listSymbols)
{
historicalFinancialTask.Add(GetFinancialsQueryAsync(symbol));
}
while (historicalFinancialTask.Count > 0)
{
var historicalFinancial = await Task.WhenAny(historicalFinancialTask);
historicalFinancialTask.Remove(historicalFinancial);
// the line below doesn't compile, which is understandable because method's return type is a Task of something
yield return new Symbol(historicalFinancial.Result.Symbol.Identifier, historicalFinancial.Result.Symbol.HistoricalQuotes, historicalFinancial.Result.Data);
}
}
private async Task<HistoricalFinancialResult> GetFinancialsQueryAsync(Symbol symbol)
{
var result = new HistoricalFinancialResult();
result.Symbol = symbol;
result.Data = await _financialsQuery.GetFinancialsQuery(symbol.Identifier); // contains some logic like parsing and use WebClient to query asynchronously
return result;
}
private class HistoricalFinancialResult
{
public Symbol Symbol { get; set; }
public IEnumerable<Financial> Data { get; set; }
// equality members
}
foreach(var symbol in await _service.GetSymbolsAsync())
{
SymbolsObservableCollection.Add(symbol);
}
最佳答案
虽然我喜欢 TPL Dataflow 组件(svick 建议您使用它),但迁移到该系统确实需要大量的 promise - 这不是您可以添加到现有设计中的东西。如果您正在执行大量 CPU 密集型数据处理并希望利用许多 CPU 内核,它会提供相当大的好处。但充分利用它并非易事。
他的另一个建议是使用 Rx,可能更容易与现有解决方案集成。 (参见 original documentation ,但对于最新的代码,请使用 Rx-Main nuget 包。或者,如果您想查看源代码,请参见 the Rx CodePlex site )甚至可以继续调用代码使用 IEnumerable<Symbol>
如果您愿意 - 您可以纯粹将 Rx 用作实现细节,[ 编辑 2013/11/09 添加: ] 尽管正如 svick 指出的那样,鉴于您的最终目标,这可能不是一个好主意。
在我给你展示一个例子之前,我想先弄清楚我们到底在做什么。您的示例有一个带有此签名的方法:
public async Task<IEnumerable<Symbol>> GetSymbolsAsync()
Task<IEnumerable<Symbol>>
,本质上说“这是一种产生
IEnumerable<Symbol>
类型的单一结果的方法,它可能不会立即产生该结果。”
Task<T>
(不管
T
可能是什么)代表单个异步操作。它可能有很多步骤(如果将
await
实现为 C#
async
方法的许多用途),但最终它会产生一件事。你想在不同的时间生产多种东西,所以
Task<T>
不太合适。
// Note: this first example is *not* what you want.
// However, it is what your method's signature promises to do.
public async Task<IEnumerable<Symbol>> GetSymbolsAsync()
{
var historicalFinancialTask = new List<Task<HistoricalFinancialResult>>();
foreach (var symbol in await _listSymbols)
{
historicalFinancialTask.Add(GetFinancialsQueryAsync(symbol));
}
var results = new List<Symbol>();
while (historicalFinancialTask.Count > 0)
{
var historicalFinancial = await Task.WhenAny(historicalFinancialTask);
historicalFinancialTask.Remove(historicalFinancial);
results.Add(new Symbol(historicalFinancial.Result.Symbol.Identifier, historicalFinancial.Result.Symbol.HistoricalQuotes, historicalFinancial.Result.Data));
}
return results;
}
IEnumerable<Symbol>
它会在元素可用时生成它们,而不是等到它们全部可用时才生成。 (否则,您也可以使用
WhenAll
。)您可以这样做,但是
yield return
不是办法。
IObservable<T>
准确表达了我相信您希望用您的
Task<IEnumerable<Symbol>>
表达的内容:它是一系列项目(就像
IEnumerable<T>
)但异步。
public Symbol GetSymbol() ...
public Task<Symbol> GetSymbolAsync() ...
public IEnumerable<Symbol> GetSymbols() ...
public IObservable<Symbol> GetSymbolsObservable() ...
Task<T>
不同,对于调用异步面向序列的方法,没有一个通用的命名约定。我在这里的末尾添加了“Observable”,但这不是普遍做法。我当然不会称它为
GetSymbolsAsync
因为人们会期望它返回一个
Task
。)
Task<IEnumerable<T>>
说“当我准备好时,我会制作这个系列”而
IObservable<T>
说:“这是一个系列。当我准备好时,我会制作每件元素。”
Symbol
序列的方法。对象,这些对象是异步生成的。这告诉我们你真的应该返回一个
IObservable<Symbol>
.这是一个实现:
// Unlike this first example, this *is* what you want.
public IObservable<Symbol> GetSymbolsRx()
{
return Observable.Create<Symbol>(async obs =>
{
var historicalFinancialTask = new List<Task<HistoricalFinancialResult>>();
foreach (var symbol in await _listSymbols)
{
historicalFinancialTask.Add(GetFinancialsQueryAsync(symbol));
}
while (historicalFinancialTask.Count > 0)
{
var historicalFinancial = await Task.WhenAny(historicalFinancialTask);
historicalFinancialTask.Remove(historicalFinancial);
obs.OnNext(new Symbol(historicalFinancial.Result.Symbol.Identifier, historicalFinancial.Result.Symbol.HistoricalQuotes, historicalFinancial.Result.Data));
}
});
}
yield return
(未编译),这将调用
OnNext
Rx 提供的对象上的方法。
IEnumerable<Symbol>
中。 ([
2013 年 11 月 29 日编辑添加: ] 虽然您可能实际上并不想这样做 - 请参阅答案末尾的补充):
public IEnumerable<Symbol> GetSymbols()
{
return GetSymbolsRx().ToEnumerable();
}
IEnumerable<Symbol>
.当然,如果数据尚不可用,任何尝试遍历该集合的代码最终都会阻塞。但关键的是,我认为你最初试图实现的目标是:
async
完成工作的方法(在我的例子中是一个委托(delegate),作为参数传递给 Observable.Create<T>
,但如果你愿意,你可以编写一个独立的 async
方法)IEnumerable<Symbol>
一旦有货,将立即生产每个单独的项目 ToEnumerable
方法中有一些巧妙的代码,可以弥补
IEnumerable<T>
的同步世界观之间的差距。和异步产生结果。 (换句话说,这正是您发现 C# 无法为您做的事情而感到失望的事情。)
ToEnumerable
可以在
https://rx.codeplex.com/SourceControl/latest#Rx.NET/Source/System.Reactive.Linq/Reactive/Linq/Observable/GetEnumerator.cs 找到。
ObservableCollection<Symbol>
.不知怎的,我没有看到那一点。这意味着
IEnumerable<T>
是错误的方法 - 您希望在项目可用时填充集合,而不是使用
foreach
环形。所以你只需这样做:
GetSymbolsRx().Subscribe(symbol => SymbolsObservableCollection.Add(symbol));
ConfigureAwait
,从而断开与 UI 线程的连接)你需要安排处理来自右侧线程上的 Rx 流:
GetSymbolsRx()
.ObserveOnDispatcher()
.Subscribe(symbol => SymbolsObservableCollection.Add(symbol));
ObserveOn
需要调度程序的过载。 (这些要求您引用
System.Reactive.Windows.Threading
。这些是扩展方法,因此您需要一个
using
作为其包含的命名空间,也称为
System.Reactive.Windows.Threading
)
关于c# - 执行 Task.WhenAny 时如何产生返回项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18284169/
我在 Chrome 上做了一些测试,requestAnimationFrame 产生了 61 fps 而 setTimeOut( callback, 0 ) 产生了 233 fps。 如果一个人想要超
当我调试代码时,我发现 GCC 和 Clang 都为 0.0/0.0 产生 nan,这是我所期望的,但 GCC 产生的 nan 将符号位设置为 1,而Clang 将其设置为 0(如果我没记错的话,与
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
我在 R Studio 中有一个时间序列。现在我想计算这个系列的log()。我尝试了以下方法: i <- (x-y) ii <- log(i) 但是我得到以下信息:Warning message: I
我有兴趣了解 JavaScript 的内部结构.我试图阅读 SpiderMonkey 的来源和 Rhino但是绕过我的头是相当复杂的。 我问的原因是:为什么像 (![]+[])[+!![]+[]] 生
我们在 Delphi 中使用标准 TWebbrowser 组件,该组件在内部使用 mshtml.dll。另外,我们使用注册表来确保页面使用新的渲染引擎( Web-Browser-Control-Spe
我必须实现一个序列化/反序列化类,并且我正在使用 System.Xml.Serialization 。我有一些IList类型属性并希望在 IList 中序列化解码属于具有特定区域性信息的列表的所有十进
我有一个 Java 应用程序,它读取包含 SQL 查询的 JSON 文件,并使用 JDBC 在数据库上触发它们。 现在我有 5 万个这样的文件,我需要生成 5 万个独立线程来读取每个文件并将它们上传到
我正在尝试将 TensorFlow 入门页面上的示例线性回归程序调整为二次回归。为此,我只是添加了另一个变量并更改了函数。然而,这似乎会导致 NaN 值。这是我的代码: import numpy as
申请后KernelPCA到我的数据并将其传递给分类器 ( SVC ) 我收到以下错误: ValueError: Input contains NaN, infinity or a value too
这背后的想法是,如果我的数据库中存在登录名(正确的用户名+密码),我将重定向到一个页面,并且在进行此身份验证后,他们可以将消息存储在文本文件中。代码非常简单尽管我不确定为什么会收到 IllegalSt
我有一个返回 log10 值的函数。在将它们转换为正常数字时,出现溢出错误。 OverflowError: (34, 'Numerical result out of range') 我检查了日志值,
nosetests 抛出一个 ImportError,尽管我认为这是一个正确配置的 virtualenv。 ==============================================
我是这个网站的新手,所以如果我做错了什么,我提前道歉。当我尝试使用 kivy-garden 的 ScrollLabel 时,它给了我一个错误。基本上我正在尝试创建一个控制台日志,并且我需要能够在文本框
任何人都对 MDSJ 有任何经验?以下输入仅产生 NaN 结果,我不明白为什么。文档非常稀少。 import mdsj.Data; import mdsj.MDSJ; public class MDS
我有一个非常简单的 scala jcuda 程序,它添加了一个非常大的数组。一切都编译和运行得很好,直到我想从我的设备复制超过 4 个字节到主机。当我尝试复制超过 4 个字节时,我收到 CUDA_ER
我正在使用 Hero 组件在两个页面之间创建动画。Hero 组件用于包装一个 Image 小部件(没问题)和一个 Container 小部件(有问题)。 抛出以下溢出错误: ══╡ EXCEPTIO
我无法理解页面 https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/void 中的这一段: This ope
当在 Angular 中使用不立即触发事件的异步管道时(http 请求或任何有延迟的可观察对象),第一个值为 null为什么会这样?如何避免这种情况? 第一个变化: SimpleChange {
如果一个导入的库生成了一个会 panic 的 goroutine 怎么办?在这种情况下,开发人员无法阻止程序退出。 就像在这段代码中一样,使用延迟恢复调用一个错误的库没有帮助,因为该库正在生成一个 p
我是一名优秀的程序员,十分优秀!