将BlockingCollection作为IEnumerable从方法返回

时间:2012-02-22 04:51:03

标签: .net multithreading asynchronous task-parallel-library async-ctp

我试图从一个由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();
});

1 个答案:

答案 0 :(得分:3)

完成向集合中添加项目后,您需要致电results.CompleteAdding()

如果不这样做,枚举将永远不会结束,Count()永远不会返回。

除此之外,您发布的代码是正确的。