我试图从一个由BlockingCollection支持的方法返回一个IEnumerable。代码模式是:
public IEnumerable<T> Execute() {
var results = new BlockingCollection<T>(10);
_ExecuteLoad(results);
return results.GetConsumingEnumerable();
}
private void _ExecuteLoad<T>(BlockingCollection<T> results) {
var loadTask = Task.Factory.StartNew(() =>
{
//some async code that adds items to results
results.CompleteAdding();
});
}
public void Consumer() {
var count = Execute().Count();
}
问题是从Execute()返回的可枚举总是为空。我见过的例子都在Task中迭代BlockingCollection。这似乎在这种情况下不起作用。
有谁知道我哪里出错了?
为了使事情更加清晰,我粘贴了我正在执行的代码来填充集合。也许有一些东西导致这里的问题?
Task.Factory.StartNew(() =>
{
var continuationRowKey = "";
var continuationParitionKey = "";
var action = HttpMethod.Get;
var queryUri = _GetTableQueryUri(tableServiceUri, tableName, query, continuationParitionKey, continuationRowKey, timeout);
while (true)
{
using (var request = GetRequest(queryUri, null, action.Method, azureAccountName, azureAccountKey))
{
request.Method = action;
request.RequestUri = queryUri;
using (var client = new HttpClient())
{
var sendTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
using (var response = sendTask.Result)
{
continuationParitionKey = // stuff from headers
continuationRowKey = // stuff from headers
var streamTask = response.Content.ReadAsStreamAsync();
using (var stream = streamTask.Result)
{
using (var reader = XmlReader.Create(stream))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "entry" && reader.NamespaceURI == "http://www.w3.org/2005/Atom")
{
results.Add(XNode.ReadFrom(reader) as XElement);
}
}
reader.Close();
}
}
}
}
if (continuationParitionKey == null && continuationRowKey == null)
break;
queryUri = _GetTableQueryUri(tableServiceUri, tableName, query, continuationParitionKey, continuationRowKey, timeout);
}
}
results.CompleteAdding();
});
答案 0 :(得分:3)
完成向集合中添加项目后,您需要致电results.CompleteAdding()
。
如果不这样做,枚举将永远不会结束,Count()
永远不会返回。
除此之外,您发布的代码是正确的。