System.AggregateException when calling method from an unsynchronized block of code
Calling the vendr API in a KonstruktAction (not async) throws an System.AggregateException with the message "Exception were thrown by listed actions.(Object synchronization method was called from an unsynchronized block of code.)".
Calling the same API from any controller (async) in the code will not throw an exception.
Would it be possible to resolve this issue?
To reproduce the issue please see the picture below.
We are on Konstrukt version 1.1.1.
at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)
at Umbraco.Cms.Core.Scoping.Scope.<>cDisplayClass106_0.2()
at Umbraco.Cms.Core.Scoping.Scope.TryFinally(Int32 index, Action[] actions)
at Umbraco.Cms.Core.Scoping.Scope.TryFinally(Int32 index, Action[] actions)
at Umbraco.Cms.Core.Scoping.Scope.TryFinally(Int32 index, Action[] actions)
at Umbraco.Cms.Core.Scoping.Scope.Dispose()
at Vendr.Umbraco.UmbracoScopeUnitOfWork.Dispose()
at FooBar.Commerce.Services.OrderUpdateService.FinalizeOrderWithCheckoutZeroValue(String emailAddress, String firstName, String lastName, String paymentMethodAlias) in C:\Repos\FooBar\backend\src\Commerce\code\Services\OrderUpdateService.cs:line 170
StackTrace of InnerExceptions
at System.Threading.Monitor.Exit(Object obj)
at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.Release(WriteLockInfo lockInfo, Boolean commit)
at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.ScopedWriteLock.Release(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContextualBase.<>c__11.<Get>b__1_1(Boolean completed, T item)
at Umbraco.Cms.Core.Scoping.ScopeContext.EnlistedObject1.Execute(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)
Maybe try swapping your UoW using statement to be an explicit using statement
using (var uow = this.vendrApi.Uow.Create())
{
// Your code here
}
I've got the feeling .NET is not sure when to dispose of the scope and when it does, it's too late. By using an explicit using code block you are defining explicitly when the resources are disposed.
Basically nothing. Please see the image below. When I debug the code, after executing the "uow.Complete();" line the service continues to run and after about half minute I got the error in the catch.
I use the same syntax there as well. But in the example I sent you last time I am not using that service. I moved the code from the service to the KonstruktAction to make sure it's not an issue with the service.
Sorry, but I need full stack traces. Fragments in screenshots means I'm potentially missing something. Also, I'm now confused to what code you are actually using.
Can you provide one clear code snippet and the full stack trace that goes along with it.
I'll stick to the first example that I sent you. Please see the stack trace and a code snippet below.
Let me know if you need anything else.
System.AggregateException: Exceptions were thrown by listed actions. (Object synchronization method was called from an unsynchronized block of code.) (Object synchronization method was called from an unsynchronized block of code.) (Object synchronization method was called from an unsynchronized block of code.)
---> System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code.
at System.Threading.Monitor.Exit(Object obj)
at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.Release(WriteLockInfo lockInfo, Boolean commit)
at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.ScopedWriteLock.Release(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContextualBase.<>c11.11(Boolean completed, T item)
at Umbraco.Cms.Core.Scoping.ScopeContext.EnlistedObject1.Execute(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)
--- End of inner exception stack trace ---
at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)
at Umbraco.Cms.Core.Scoping.Scope.<>cDisplayClass1060.
---> (Inner Exception #2) System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code.
at System.Threading.Monitor.Exit(Object obj)
at Umbraco.Cms.Infrastructure.PublishedCache.SnapDictionary2.Release(WriteLockInfo lockInfo, Boolean commit)
at Umbraco.Cms.Infrastructure.PublishedCache.SnapDictionary2.ScopedWriteLock.Release(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContextualBase.<>c11.1_1(Boolean completed, T item)
at Umbraco.Cms.Core.Scoping.ScopeContext.EnlistedObject1.Execute(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)<---
Edit: Tried to get the whole stack to be visible but Umbraco forum seems to cut it down in length.
I have tried splitting up the code and turned out that the Finalize() causes the issue. If I remove it from the code, everything goes well, and if I try to move it to a separate UoW then we get the same error again.
at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)
at Umbraco.Cms.Core.Scoping.Scope.<>cDisplayClass106_0.2()
at Umbraco.Cms.Core.Scoping.Scope.TryFinally(Int32 index, Action[] actions)
at Umbraco.Cms.Core.Scoping.Scope.TryFinally(Int32 index, Action[] actions)
at Umbraco.Cms.Core.Scoping.Scope.TryFinally(Int32 index, Action[] actions)
at Umbraco.Cms.Core.Scoping.Scope.Dispose()
at FooBar.Storage.Konstrukt.Actions.GenerateCodeBatchAction.Execute(String collectionAlias, Object[] entityIds, GenerateCodeActionSettings generateCodeActionSettings) in C:\Repos\FooBar\backend\src\Storage\code\Konstrukt\Actions\GenerateCodeBatchAction.cs:line 119
at System.Threading.Monitor.Exit(Object obj)
at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.Release(WriteLockInfo lockInfo, Boolean commit)
at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.ScopedWriteLock.Release(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContextualBase.<>c__11.<Get>b__1_1(Boolean completed, T item)
at Umbraco.Cms.Core.Scoping.ScopeContext.EnlistedObject1.Execute(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)
at System.Threading.Monitor.Exit(Object obj)
at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.Release(WriteLockInfo lockInfo, Boolean commit)
at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.ScopedWriteLock.Release(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContextualBase.<>c__11.<Get>b__1_1(Boolean completed, T item)
at Umbraco.Cms.Core.Scoping.ScopeContext.EnlistedObject1.Execute(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)
at System.Threading.Monitor.Exit(Object obj)
at Umbraco.Cms.Infrastructure.PublishedCache.SnapDictionary2.Release(WriteLockInfo lockInfo, Boolean commit)
at Umbraco.Cms.Infrastructure.PublishedCache.SnapDictionary2.ScopedWriteLock.Release(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContextualBase.<>c__11.<Get>b__1_1(Boolean completed, T item)
at Umbraco.Cms.Core.Scoping.ScopeContext.EnlistedObject1.Execute(Boolean completed)
at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)
Ok, well if you are able to upgrade to the latest v2 I've just built a new beta of the next 2.3.3 release which you can find on our unstable NuGet feed at https://nuget.outfield.digital/unstable/vendr/v3/index.json (v2.3.3-beta004 is the version you'll want to test).
In that release I've switched our AsyncHelper to use a different approach that we are using in the v3 branch. I'm not saying this is the answer yet, but I think it's worth a try.
System.AggregateException when calling method from an unsynchronized block of code
Calling the vendr API in a KonstruktAction (not async) throws an System.AggregateException with the message "Exception were thrown by listed actions.(Object synchronization method was called from an unsynchronized block of code.)".
Calling the same API from any controller (async) in the code will not throw an exception.
Would it be possible to resolve this issue?
To reproduce the issue please see the picture below. We are on Konstrukt version 1.1.1.
Hi, can you please post the full stack trace?
at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed) at Umbraco.Cms.Core.Scoping.Scope.<>cDisplayClass106_0.2() at Umbraco.Cms.Core.Scoping.Scope.TryFinally(Int32 index, Action[] actions) at Umbraco.Cms.Core.Scoping.Scope.TryFinally(Int32 index, Action[] actions) at Umbraco.Cms.Core.Scoping.Scope.TryFinally(Int32 index, Action[] actions) at Umbraco.Cms.Core.Scoping.Scope.Dispose() at Vendr.Umbraco.UmbracoScopeUnitOfWork.Dispose() at FooBar.Commerce.Services.OrderUpdateService.FinalizeOrderWithCheckoutZeroValue(String emailAddress, String firstName, String lastName, String paymentMethodAlias) in C:\Repos\FooBar\backend\src\Commerce\code\Services\OrderUpdateService.cs:line 170
StackTrace of InnerExceptions
at System.Threading.Monitor.Exit(Object obj) at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.Release(WriteLockInfo lockInfo, Boolean commit) at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.ScopedWriteLock.Release(Boolean completed) at Umbraco.Cms.Core.Scoping.ScopeContextualBase.<>c__1
1.<Get>b__1_1(Boolean completed, T item) at Umbraco.Cms.Core.Scoping.ScopeContext.EnlistedObject
1.Execute(Boolean completed) at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)Ok,
Maybe try swapping your UoW using statement to be an explicit using statement
I've got the feeling .NET is not sure when to dispose of the scope and when it does, it's too late. By using an explicit
using
code block you are defining explicitly when the resources are disposed.Matt
I have just tried it, but I unfortunately I got the same error.
What's the code in
OrderUpdateService
on line 170?Basically nothing. Please see the image below. When I debug the code, after executing the "uow.Complete();" line the service continues to run and after about half minute I got the error in the catch.
Are you opening a unit of work inside the
OrderUpdateService
as if so, I'd maybe suggest ensuring that uses the sameusing
syntax.Matt
I use the same syntax there as well. But in the example I sent you last time I am not using that service. I moved the code from the service to the KonstruktAction to make sure it's not an issue with the service.
If you are not using the service, why is it referenced in the stack trace?
Sorry that was my bad. I reproduced the same issue from the service and pasted the stack trace of it. So herby the screenshot from the service.
Sorry, but I need full stack traces. Fragments in screenshots means I'm potentially missing something. Also, I'm now confused to what code you are actually using.
Can you provide one clear code snippet and the full stack trace that goes along with it.
Sorry for the confusion.
I'll stick to the first example that I sent you. Please see the stack trace and a code snippet below. Let me know if you need anything else.
System.AggregateException: Exceptions were thrown by listed actions. (Object synchronization method was called from an unsynchronized block of code.) (Object synchronization method was called from an unsynchronized block of code.) (Object synchronization method was called from an unsynchronized block of code.) ---> System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code. at System.Threading.Monitor.Exit(Object obj) at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.Release(WriteLockInfo lockInfo, Boolean commit) at Umbraco.Cms.Infrastructure.PublishedCache.ContentStore.ScopedWriteLock.Release(Boolean completed) at Umbraco.Cms.Core.Scoping.ScopeContextualBase.<>c11.11(Boolean completed, T item) at Umbraco.Cms.Core.Scoping.ScopeContext.EnlistedObject1.Execute(Boolean completed) at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed) --- End of inner exception stack trace --- at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed) at Umbraco.Cms.Core.Scoping.Scope.<>cDisplayClass1060.
---> (Inner Exception #2) System.Threading.SynchronizationLockException: Object synchronization method was called from an unsynchronized block of code. at System.Threading.Monitor.Exit(Object obj) at Umbraco.Cms.Infrastructure.PublishedCache.SnapDictionary2.Release(WriteLockInfo lockInfo, Boolean commit) at Umbraco.Cms.Infrastructure.PublishedCache.SnapDictionary2.ScopedWriteLock.Release(Boolean completed) at Umbraco.Cms.Core.Scoping.ScopeContextualBase.<>c11.1_1(Boolean completed, T item) at Umbraco.Cms.Core.Scoping.ScopeContext.EnlistedObject1.Execute(Boolean completed) at Umbraco.Cms.Core.Scoping.ScopeContext.ScopeExit(Boolean completed)<---
Edit: Tried to get the whole stack to be visible but Umbraco forum seems to cut it down in length.
Hmm, I'm struggling to think why running in an action is any different to running in an API controller TBH.
The actions are triggered from a controller, and all the code should be run synchronously so I'm not sure what would be causing it to do this.
Ultimately this looks like it's a scope issue in core (Vendr's UoW just wraps Umbraco's scopes) but I can't really see what would be causing that.
Have you tried stripping that action back and only performing one order update at a time to see if it's a specific Vendr API call that is causing it?
I have tried splitting up the code and turned out that the Finalize() causes the issue. If I remove it from the code, everything goes well, and if I try to move it to a separate UoW then we get the same error again.
Hmmm,
The only thing I can think could be related is Vendr sending out the confirmation email on finalized order.
This get's sent synchronously, but the API's for that are async so we use an AsyncHelper to force the async API to run sync.
The annoying thing is there is nothing that mentiones Vendr or Konstrukt in your stack trace so a little hard to prove.
You could try removing the finalized order email sending handler to see if this is the issue. In your startup/composer you can unregister the handler
Obviously you'll want to the handler to run, but we can at least see if it is this that is causing the problems.
Yes, that is indeed the problem. Do you know how to proceed?
What version of Vendr are you using?
We are on version 2.1.2
Ok, well if you are able to upgrade to the latest v2 I've just built a new beta of the next 2.3.3 release which you can find on our unstable NuGet feed at https://nuget.outfield.digital/unstable/vendr/v3/index.json (v2.3.3-beta004 is the version you'll want to test).
In that release I've switched our AsyncHelper to use a different approach that we are using in the v3 branch. I'm not saying this is the answer yet, but I think it's worth a try.
Are you able to try this?
Matt
Thank you! I upgraded to v2.3.3-beta004 and it works now! Would it be possible to keep that approach and release it anytime soon?
Perfect!
You can use the beta for now, but should be able to release the 2.3.3 patch by the end of the week/early next
Great! Thank you very much!
Bibi
is working on a reply...