我收到以下错误,只有当多个用户点击同一个按钮时才会出现此错误。任何帮助/想法将非常感激:
System.InvalidOperationException:修改了集合;列举 操作可能无法执行。生成:2015年6月10日星期三07:29:06 GMT
AutoMapper.AutoMapperMappingException:
映射类型:用户 - > User ApplicationSecurityManager.Service.User - > ApplicationSecurityManager.Models.User
目的地路径:用户
来源价值:ApplicationSecurityManager.Service.User ---> System.InvalidOperationException:集合已被修改;列举 操作可能无法执行。在 System.Collections.Generic.List
1.Enumerator.MoveNextRare() at AutoMapper.TypeMap.<get_AfterMap>b__1(Object src, Object dest) at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.Map(ResolutionContext context, IMappingEngineRunner mapper) at AutoMapper.Mappers.TypeMapMapper.Map(ResolutionContext context, IMappingEngineRunner mapper) at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) --- End of inner exception stack trace --- at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) at AutoMapper.MappingEngine.Map[TDestination](Object source, Action
1 opts)at ApplicationSecurityManager.UserManager.LoadUser(String username)at ApplicationSecurityManager.UserManager.get_AuthenticatedUser()at ApplicationSecurityManager.UserManager.IsAuthenticated()at ApplicationSecurityManager.Infrastructure.ApplicationSecurityAttribute.OnAuthorization(AuthorizationContext filterContext)at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext,IList1 filters, ActionDescriptor actionDescriptor) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult
1.Begin(AsyncCallback 回调,对象状态,Int32超时)at System.Web.Mvc.Async.AsyncResultWrapper.Begin [TResult](的AsyncCallback 回调,对象状态,BeginInvokeDelegate beginDelegate, EndInvokeDelegate1 endDelegate, Object tag, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate
1 endDelegate,Object tag)at System.Web.Mvc.Controller&LT;&GT; c__DisplayClass1d.b__17(的AsyncCallback asyncCallback,Object asyncState)at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate
1 endDelegate,Object tag,Int32 timeout)at System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback回调, 对象状态) System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate
1 endDelegate,Object tag,Int32 timeout)at System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback回调, 对象状态,BeginInvokeDelegate beginDelegate,EndInvokeDelegate endDelegate,Object tag)at System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback回调,对象状态) System.Web.Mvc.MvcHandler&LT;&GT; c__DisplayClass8.b__2(的AsyncCallback asyncCallback,Object asyncState)at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate
1 endDelegate,Object tag,Int32 timeout)at System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback回调, 对象状态,BeginInvokeDelegate beginDelegate,EndInvokeDelegate endDelegate,Object tag)at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext,AsyncCallback回调,对象状态)at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 在System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤, 布尔和放大器; completedSynchronously)
这是构造函数,我认为aftermap是问题但是在调试时我没有收到错误。
Public Sub New(environmentCode As String, applicationCode As String)
MyBase.New(environmentCode, applicationCode)
SOBaseUrl = System.Configuration.ConfigurationManager.AppSettings(Enums.AppSettingKeys.SOBaseUrl.ToString())
If Not String.IsNullOrEmpty(SOBaseUrl) Then
SOBaseUrl = SOBaseUrl.TrimEnd("/")
End If
'Setup mapping.
Mapper.CreateMap(Of Service.User, Models.User)() _
.ForMember(Function(dest As Models.User) dest.ENumber, Sub(opt) opt.MapFrom(Function(src As Service.User) src.INumber)) _
.AfterMap(Sub(src As Service.User, dest As Models.User)
dest.Groups = New List(Of String)
Using service = ApplicationSecurityManager.Service.Factory.GetService()
Dim applicationPermissions = service.LoadPermissionsForUser(dest.Username, MyBase.EnvironmentCode)
If (Not applicationPermissions Is Nothing AndAlso applicationPermissions.Any(Function(x) x.Code = MyBase.ApplicationCode)) Then
dest.Groups = applicationPermissions.Single(Function(x) x.Code = MyBase.ApplicationCode).GroupNames.ToList()
End If
End Using
End Sub)
Depenendency Injection Mapping:
container.RegisterType(Of IUserManager, UserManager)(New PerThreadLifetimeManager(),
New InjectionConstructor(
ConfigurationManager.AppSettings(Common.Enums.AppSettingKeys.Environment.ToString()),
ConfigurationManager.AppSettings(Common.Enums.AppSettingKeys.ApplicationCode.ToString()))
)
在saveUserResponse
中,错误将被抛出。
Public Function Create(user As Common.Models.User, approve As Boolean) As SO.Common.Models.User Implements IUserProvider.Save
Dim saveUserResponse = UserManager.SaveUser(Mapper.Map(Of ApplicationSecurityManager.Service.User)(user))
If Not String.IsNullOrEmpty(saveUserResponse.ErrorMessage) Then
'The Security system returned an error.
Throw New Exception("Security Service returned error: " & saveUserResponse.ErrorMessage)
End If
'Return the username.
Return Mapper.Map(Of Common.Models.User)(saveUserResponse.User)
End Function
答案 0 :(得分:1)
This is pretty common mistake modifying a collection while iterating it. Is it possible you are leaving something out here we can't see? Anyway's in the code that you have provided there is not any such scenario from what I can see. This means that you might be calling this in a multi-threaded environment and the collection is being modified in some other thread.
What can you try?
Look into locking your enumeration
so only one thread at a time can be accessed. It's possible that it's being accessed multiple time's when user's are clicking on the button.
Here's a good link to help you out: http://weblogs.asp.net/leftslipper/mvc-locking-the-routecollection
答案 1 :(得分:1)
当多个用户在映射的AfterMap()方法中修改相同的user.Groups集合时,会导致这种情况。要避免这种情况,请锁定正在处理集合的代码。例如:
'class level object
private object _myLock = New object()
'Setup mapping.
Mapper.CreateMap(Of Service.User, Models.User)() _
.ForMember(Function(dest As Models.User) dest.ENumber, Sub(opt) opt.MapFrom(Function(src As Service.User) src.INumber)) _
.AfterMap(Sub(src As Service.User, dest As Models.User)
SyncLock _myLock
dest.Groups = New List(Of String)
Using service = ApplicationSecurityManager.Service.Factory.GetService()
Dim applicationPermissions = service.LoadPermissionsForUser(dest.Username, MyBase.EnvironmentCode)
If (Not applicationPermissions Is Nothing AndAlso applicationPermissions.Any(Function(x) x.Code = MyBase.ApplicationCode)) Then
dest.Groups = applicationPermissions.Single(Function(x) x.Code = MyBase.ApplicationCode).GroupNames.ToList()
End If
End Using
End SyncLock
End Sub)