从数据库并行反序列化 Json
场景如下:在一个单独的任务中,我从数据读取器读取数据,该数据读取器表示带有字符串(JSON)的单列结果集。在该任务中,我将 JSON 字符串添加到包装 ConcurrentQueue 的 BlockingCollection 中。同时,在主线程中,我尝试从集合中获取/出列 JSON 字符串,然后将其反序列化并返回。
从数据库读取和反序列化的速度大致相同,因此不会因大型BlockingCollection而导致太多内存消耗。
从数据库读取完成后,任务将关闭,然后我将反序列化所有非反序列化的 JSON 字符串。
问题/想法:
1) TryTake 是否锁定,从而无法进行添加?
2)不要这样做。只需串行执行并产生返回即可。
using (var q = new BlockingCollection<string>())
{
Task task = null;
try
{
task = new Task(() =>
{
foreach (var json in sourceData)
q.Add(json);
});
task.Start();
while (!task.IsCompleted)
{
string json;
if (q.TryTake(out json))
yield return Deserialize<T>(json);
}
Task.WaitAll(task);
}
finally
{
if (task != null)
{
task.Dispose();
}
q.CompleteAdding();
}
foreach (var e in q.GetConsumingEnumerable())
yield return Deserialize<T>(e);
}
This is the scenario: In a separate task I read from a datareader which represent a single column result set with a string, a JSON. In that task I add the JSON string to a BlockingCollection that wraps the ConcurrentQueue. At the same time in the main thread I TryTake/dequeue a JSON string from the collection and then yield return it deserialized.
The reading from the database and the deserialization is approximately of the same speed so there will not be to much memory consumption caused by a large BlockingCollection.
When the reading from the database is done, the task is closed and I then deserialize all the non deserialized JSON strings.
Questions/thoughts:
1) Does the TryTake lock so that no adding can be done?
2) Don't do it. Just do it in serial and yield return.
using (var q = new BlockingCollection<string>())
{
Task task = null;
try
{
task = new Task(() =>
{
foreach (var json in sourceData)
q.Add(json);
});
task.Start();
while (!task.IsCompleted)
{
string json;
if (q.TryTake(out json))
yield return Deserialize<T>(json);
}
Task.WaitAll(task);
}
finally
{
if (task != null)
{
task.Dispose();
}
q.CompleteAdding();
}
foreach (var e in q.GetConsumingEnumerable())
yield return Deserialize<T>(e);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题1
将有一段非常短暂的时间无法执行添加,但是这段时间可以忽略不计。来自http://msdn.microsoft.com/en-us/library/dd997305。 ASPX
问题2:
这似乎是可行的方法。与任何优化工作一样 - 做最简单的事情,然后进行测量!如果这里存在瓶颈,请考虑优化,但至少您会知道您的“优化”是否确实通过指标进行比较而有所帮助。
Question 1
There will be a very brief period whereby an add cannot be performed, however this time will be negligible. From http://msdn.microsoft.com/en-us/library/dd997305.aspx
Question 2:
This seems like the way to go. As with any optimisation work - do what is simplest and then measure! If there is a bottleneck here consider optimising, but at least you'll know if your 'optimistations' are actually helping by virtue of having metrics to compare against.