c# – 添加AsParallel()调用会导致我的代码在写入文件时中断
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 添加AsParallel()调用会导致我的代码在写入文件时中断,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3402字,纯文字阅读大概需要5分钟。
内容图文
我正在构建一个必须处理大量文档的控制台应用程序.
为了保持简单,这个过程是:
>对于X和Y之间的每年,查询数据库以获取要处理的文档引用列表
>对于每个参考,处理本地文件
我认为,这个过程方法是独立的,只要输入参数不同,就应该并行化:
private static bool ProcessDocument(
DocumentsDataset.DocumentsRow d,
string langCode
)
{
try
{
var htmFileName = d.UniqueDocRef.Trim() + langCode + ".htm";
var htmFullPath = Path.Combine("x:\path", htmFileName;
missingHtmlFile = !File.Exists(htmFullPath);
if (!missingHtmlFile)
{
var html = File.ReadAllText(htmFullPath);
// ProcessHtml is quite long : it use a regex search for a list of reference
// which are other documents, then sends the result to a custom WS
ProcessHtml(ref html);
File.WriteAllText(htmFullPath, html);
}
return true;
}
catch (Exception exc)
{
Trace.TraceError("{0,8}Fail processing {1} : {2}","[FATAL]", d.UniqueDocRef, exc.ToString());
return false;
}
}
为了枚举我的文档,我有这个方法:
private static IEnumerable<DocumentsDataset.DocumentsRow> EnumerateDocuments()
{
return Enumerable.Range(1990, 2020 - 1990).AsParallel().SelectMany(year => {
return Document.FindAll((short)year).Documents;
});
}
Document是一个包装文档检索的业务类.此方法的输出是一个类型化数据集(我正在返回Documents表).该方法等待了一年,我确信文档不能超过一年(实际上是年份的一部分).
注意在这里使用AsParallel(),但我从未遇到过这个问题.
现在,我的主要方法是:
var documents = EnumerateDocuments();
var result = documents.Select(d => {
bool success = true;
foreach (var langCode in new string[] { "-e","-f" })
{
success &= ProcessDocument(d, langCode);
}
return new {
d.UniqueDocRef,
success
};
});
using (var sw = File.CreateText("summary.csv"))
{
sw.WriteLine("Level;UniqueDocRef");
foreach (var item in result)
{
string level;
if (!item.success) level = "[ERROR]";
else level = "[OK]";
sw.WriteLine(
"{0};{1}",
level,
item.UniqueDocRef
);
//sw.WriteLine(item);
}
}
此方法在此表单下按预期工作.但是,如果我更换
var documents = EnumerateDocuments();
通过
var documents = EnumerateDocuments().AsParrallel();
它停止工作,我不明白为什么.
错误出现在这里(在我的处理方法中):
File.WriteAllText(htmFullPath, html);
它告诉我该文件已被另一个程序打开.
我不明白是什么原因导致我的程序无法按预期工作.由于我的文档变量是IEnumerable返回的唯一值,为什么我的流程方法会破坏?
thx建议
[编辑]检索文件的代码:
/// <summary>
/// Get all documents in data store
/// </summary>
public static DocumentsDS FindAll(short? year)
{
Database db = DatabaseFactory.CreateDatabase(connStringName); // MS Entlib
DbCommand cm = db.GetStoredProcCommand("Document_Select");
if (year.HasValue) db.AddInParameter(cm, "Year", DbType.Int16, year.Value);
string[] tableNames = { "Documents", "Years" };
DocumentsDS ds = new DocumentsDS();
db.LoadDataSet(cm, ds, tableNames);
return ds;
}
[编辑2]我的问题的可能来源,感谢mquander.如果我写道:
var test = EnumerateDocuments().AsParallel().Select(d => d.UniqueDocRef);
var testGr = test.GroupBy(d => d).Select(d => new { d.Key, Count = d.Count() }).Where(c=>c.Count>1);
var testLst = testGr.ToList();
Console.WriteLine(testLst.Where(x => x.Count == 1).Count());
Console.WriteLine(testLst.Where(x => x.Count > 1).Count());
我得到这个结果:
0
1758
删除AsParallel会返回相同的输出.
结论:我的EnumerateDocuments有错误,每个文档返回两次.
我想要在这里潜水
这可能是我原因中的源枚举
解决方法:
是Document.FindAll((短)年).Documents threadsafe?因为第一个和第二个版本之间的区别在于第二个(损坏)版本,所以此调用同时运行多次.这可能是问题的原因.
内容总结
以上是互联网集市为您收集整理的c# – 添加AsParallel()调用会导致我的代码在写入文件时中断全部内容,希望文章能够帮你解决c# – 添加AsParallel()调用会导致我的代码在写入文件时中断所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。