并行。递归方法的foreach -- c# 领域 和 .net-4.0 领域 和 task-parallel-library 领域 相关 的问题

Parallel.ForEach in recursive method


1
vote

问题

中文

我有一种方法,可以收集与数据库的共享信息和写入结果, 我使用并行.Foreach,提高性能,特别是如果扫描100 TB

如果我在本地数据库中运行此代码,我没有问题,但在沙箱数据库上我得到了几吨例外/ 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()   

如果我删除并行。向往并使用正常循环,然后在应用程序需要年龄才能运行时,我没有问题。

英文原文

I have a method that collect shares information and write results to database, I use Parallel.Foreach which increased the performance especially if scanning 100 TB

If i run this code in my local database, i have no issues, but on the sandbox database i got tons of exceptions / innerExceptions

Code:

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;        } 

Writing to database:

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);     } 

Exceptions:

    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() 

If i remove the Parallel.Foreach and use normal for loop then i have no issue beside that the application takes ages to run.

        
       
       

回答列表

1
 
vote
vote
最佳答案
 

首先尝试更换此

  self.mpl_canvas.draw()  2  

用这个

  self.mpl_canvas.draw()  3  

和第二锁相同。

虽然它是一种更好的方法来实现您想要的是并行方式,但它也可能有助于在本地重现相同的错误,因为它应该增加数据库活动。

我认为依赖于数据库事务的实际问题 - 在并发数据库期间,在表中的中间结果中,表格中的结果返回无效数据;在我们看到实际查询和表格模式之前,我不能说更多。

 

First of all try replacing this

lock (shareCollectionNode) {     shareCollectionNode.AddNode(NodesLookUp(directory, maximumLevel - 1)); } 

with this

var node = NodesLookUp(directory, maximumLevel - 1); lock (shareCollectionNode) {     shareCollectionNode.AddNode(node); } 

and the same for second lock.

Although it's a better way to achieve what you want by paralleling, also it may help to reproduce the same errors locally, as it should increase database activity.

The actual issue I think relies on DataBase transactions - looks like during concurrent database operations result in intermediate results in tables which returns not valid data; I cannot say more until we see actual queries and table schema.

 
 

相关问题

0  将值动态为C#中的子类分配值  ( Dynamically assigning values to a child class in c sharp ) 
如何根据继承类的价值在C#中动态加载子类? 我有一个继承实体的类,因为我不能将父类投射到其子类型我想要动态加载实体数据,而不明确地定义每个属性。 我尝试通过使用foreach循环循环执行它,但如您所知,无法为foreach变量分配值。 我的失败尝试: def edit @user = User.fin...

1  SignalR:远程服务器返回错误:(500)Inter NAL服务器错误  ( Signalr the remote server returned an error 500 inter nal server error ) 
我已在MVC项目中安装了SignalR的客户端和服务器;我能从Web客户端致电我的集线器; var testHub; $(function () { // Setup SignalR testHub = $.connection.myhub; testHub.msg = function...

0  使用与XML的正则表达式[复制]  ( Using regex expression with xml ) 
这个问题已经在这里有答案: 如何解析XML文件? [关闭] (12个答案) ...

4  ASP.NET MVC 3获取JS中的编辑器ID和名称  ( Asp net mvc 3 get editor id and name in js ) 
我想知道是否有可能获取生成元素的HTML属性"ID" ,Link Asp.NET Web Formene.ClientID。 所以我想要完成的是在JavaScript中获取ID。 目前我正在研究形式验证者,所以我有 剃刀模板 @Html.TextEditorFor(m => m.aspnet_Membership...

2  如何使用ajax创建/删除表格行,表单控件?  ( How can i create delete a table row with form controls using ajax ) 
我有一个表,其中包含几行包含具有自己更新面板的用户控件。我需要能够在此表中创建新行,其中每列包含TextBox控件。我不想在更新面板中包装整个表格以获得显而易见的原因,但希望能够在没有完整回发的情况下创建/删除新行,并将文本框控件注册/解除注册/从页面,不必重建整个表格。 任何思想/如果如何完成? ...

0  通过P / Invoke的取消标志时需要同步吗?  ( Is synchronization required when passing a cancel flag with p invoke ) 
我通过p /调用通过引用(或通过指针)通过CALL C ++ DLL传递取消标志。标志将在C#代码中的某个时间设置,而C ++代码检查标志并在设置标志时返回。是否需要在某处进行同步? 随着C ++代码在C#代码写入标志时读取标志,存在数据竞争。 "有效的现代C ++" 建议使用STD :: Atomic进行并发,以避...

0  如何在ASP.NET MVC中使用实体框架添加数据库的条目?  ( How to add entries to database using entity framework in asp net mvc ) 
我正在尝试在我的观点中从HTML表单添加到我的数据库中的条目,但我不确定我的代码是否是一个很好的做法。我真的挣扎着匹配的属性,但我不确定我是怎么做到的。 这是我的代码: 控制器: cinereservacionEntities CineBD = new cinereservacionEntities(); [...

0  填充列表查看与列表<list <string >>  ( Populating listview with listliststring ) 
我在c#中编码了,并且我有几列的ListView控件,我想知道,我如何从 sortState <- byState[order(na.omit(byState$"Hospital.30.Day.Death..Mortality..Rates.from.Heart.Failure")),] 1 添加项目。我能够用添加物...

19  使用WinForms的实体框架UI验证  ( Entity framework ui validation using winforms ) 
我有兴趣使用Winforms应用程序和实体框架设置客户端验证5.我理解有IValidatableObject接口,我可以实现我可能需要的执行和自定义验证,以便我可能需要每个实体。 但是,由于我正在使用WinForms,我想在填写表单时使用验证错误时,使用errorProvider将用户呈现出色通知。是否能够使用Iv...

0  如何使图像顺利移动?  ( How can i make an image move smoothly ) 
我具有以面板上的鼠标移动移动的形式的图片框映像。 它在我想要它时移动,但它一直闪烁(如刷新),我了解到它是表单的问题。 我在形式的构造函数中尝试了以下代码行,但没有成功: def edit @user = User.find(session["user_id"]) render 'edit'...

13  如何检查两个对象是否仅在其属性方面都是相等的,而不破坏现有对象.Equals()?  ( How do i check if two objects are equal in terms of their properties only withou ) 
基本上,即使它们对属性的值包含相同的值......为什么默认返回diff hashcodes?为什么 public class User { public Int32 Id { get; set; } public String Username { get; set; } } User a =...

1  在UWP中绑定令人垂涎的集合  ( Bind obserable collection to menuflyoutsubitem in uwp ) 
目前我得到"物业" 项目"没有一个可访问的Setter。" 如何修改此控件,允许我将集合绑定到它,也许只需将集合中对象的属性设置为项目的文本属性? <AppBarButton x:Name="Button" Icon="Add" Label="stuff"> <AppBar...

0  滚动WPF DataGrid以特定行并侧重于该行  ( Scrolling wpf datagrid to particular row and focus that row ) 
我的要求是滚动WPF数据网格并达到特定行并侧重于该行 我正在使用以下代码来实现它。滚动到特定行正在顺利工作,但很少几次焦点不起作用 private void FocusNextRow() { int index = indexOfRowsToHighlight[indexOfRo...

2  stringbuilder与padleft /右outofmemoryexception  ( Stringbuilder used with padleft right outofmemoryexception ) 
所有,我有以下 Append 我正在为固定文本文件生成单行时,我正在执行,因为固定文本文件 formattedLine.Append(this.reversePadding ? strData.PadLeft(this.maximumLength) : ...

0  在肯尼托的Web部件中的文件上传拖放的最佳选择  ( Best option for file upload drag and drop in web part in kentico ) 
我需要一个文件上传,将选项作为kentico的Web部件。我需要在文件系统中上传文件 D:Uploadfile 如图所示,我还需要添加多个文件,删除文件,重命名文件等的选项... 我怎么走这个? ...




© 2021 it.wenda123.org All Rights Reserved. 问答之家 版权所有


Licensed under cc by-sa 3.0 with attribution required.