Parallel.ForEach递归方法
我有收集共享信息和结果写入数据库, 的方法我用Parallel.Foreach这就增加了性能,特别是如果扫描100 TBParallel.ForEach递归方法
如果我在本地运行这段代码数据库,我觉得没有问题,但沙盒数据库上我得到吨例外/ innerExceptions
代码:
private static INodeCollection NodesLookUp(string path, int maximumLevel) {
var shareCollectionNode = new ShareCollection(path);
shareCollectionNode.GetNodeProperties();
shareCollectionNode.GetPermissionEntires();
WriteNodeToDatabase(shareCollectionNode); // write collected infomation to database
if (maximumLevel <= 0 && _maximumSubLevels != -1)
{
return shareCollectionNode;
}
Parallel.ForEach(Directory.GetDirectories(shareCollectionNode.FullPath), directory =>
{
try
{
lock (shareCollectionNode)
{
shareCollectionNode.AddNode(NodesLookUp(directory, maximumLevel - 1));
}
}
catch (UnauthorizedAccessException unauthorizedAccessException)
{
lock (_shareIssues)
{
_shareIssues.Add(new ShareIssue(TraceStatu.UnauthorizedAccess, directory,
unauthorizedAccessException.Message, dfsId, currentLevel));
}
}
});
return shareCollectionNode;
}
写入到数据库:
个private static void WriteNodeToDatabase(ShareCollection shareCollection) {
var nodeId = Persistence.UpsertShare(shareCollection);
var sharePermissions = new List<IPermissionRight>();
foreach (var permissionEntry in shareCollection.PermissionEntries)
{
permissionEntry.NodeId = nodeId;
var permissionEntryId = Persistence.InsertPermissionEntry(permissionEntry);
permissionEntry.SetPermissions(permissionEntryId);
sharePermissions.AddRange(permissionEntry.Permissions);
}
Persistence.InsertPermissions(sharePermissions);
}
例外:
System.Data.SqlClient.SqlException (0x80131904): Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
如果我删除Parallel.Foreach和使用正常的循环,然后我有一个应用程序需要年龄运行身边没有问题。
回答:
首先尝试用这种
var node = NodesLookUp(directory, maximumLevel - 1); lock (shareCollectionNode)
{
shareCollectionNode.AddNode(node);
}
与同为第二锁更换这
lock (shareCollectionNode) {
shareCollectionNode.AddNode(NodesLookUp(directory, maximumLevel - 1));
}
。
虽然这是一种更好的方式来通过并行来实现您想要的功能,但也可能有助于在本地重现相同的错误,因为它会增加数据库活动。
我认为依赖于DataBase事务的实际问题 - 看起来像在并发数据库操作期间导致返回无效数据的表中的中间结果;除非我们看到实际的查询和表格模式,否则我不能多说。
以上是 Parallel.ForEach递归方法 的全部内容, 来源链接: utcz.com/qa/267005.html