Exception in AdvisableCollection

michael.proepster's Avatar

michael.proepster

01 Dec, 2017 11:21 AM

I got this exception, but I am sure that I marked everything as Reader

PostSharp.Patterns.Threading.ThreadAccessException: The current thread does not have the permission to access the object. Ensure the object entry point (i.e. the public/internal method or the delegate callback method) is annotated with the [Reader] custom attribute.

   at PostSharp.Patterns.Threading.Controllers.ConcurrencyController.RequireAccess(ObjectAccessLevel objectAccessLevel)
   at PostSharp.Patterns.Collections.AdvisableCollection`1.Enumerator.MoveNext()
   at PostSharpDemo.Form1.buttonEnumeratorTest_Click(Object sender, EventArgs e) in C:\dev\T1gui_PostSharpEval\50_src\PostSharpDemo\Form1.cs:line 203
   at System.Windows.Forms.Control.OnClick(EventArgs e)

I attached the example project to reproduce. Just start the application and click on the button "Enumerator Test".

  1. Support Staff 1 Posted by PostSharp Techn... on 05 Dec, 2017 02:37 PM

    PostSharp Technologies's Avatar

    Hello,

    In your sample project the ItemGroup.GetEnumerator method only creates and returns a new instance of enumerator, while the Form1.buttonEnumeratorTest_Click method initiates a Read access by performing enumeration. In our current implementation a collection enumerator never attempts to acquire a Read access (lock), it only validates that the Read access is available.

    This means that you can enumerate a synchronized collection only within a method that itself has a Read access.

    There's also one workaround that we have implemented for the purpose of WPF data binding. When an enumerator is created outside of the context of the threading model, a copy of the collection is created and an enumerator of that copy is returned to the caller.

    The workaround in your example would be to also create a copy of the collection and return its enumerator.

            [Reader]
            public override IEnumerator<IItem> GetEnumerator()
            {
                return _advisableCollection.Cast<IItem>().ToList<IItem>().GetEnumerator();
            }
    

    We understand that the current state is not optimal, but unfortunately more complex design for threading and enumerators did not fit into 4.3 and 5.0 scope.
    We have filed an issue (#15700) for version 5.1 to look for more optimal and clean solution.

    -alex

  2. 2 Posted by michael.proepst... on 06 Dec, 2017 10:13 AM

    michael.proepster's Avatar

    As I understand this, the actual problem is that my GetEnumerator method is attributed with [Reader]. If I were able to not do that, the AdvisableCollection.GetEnumerator would work correctly ?

    I can live with the workaround, thanks.

  3. Support Staff 3 Posted by PostSharp Techn... on 11 Dec, 2017 06:14 PM

    PostSharp Technologies's Avatar

    Hello,

    If you were able to not apply a [Reader] (or similar attribute) to the GetEnumerator method then the enumeration test would not throw an exception. Marking the method with [ExplicitlySynchronized] doesn't work either, because the method will still execute in the threading context (with unchecked access level).

    The existing workaround was implemented for the case when you need to directly enumerate a property that has AdvisableCollection<T> type. For example, if you change the classes to derive from AdvisableCollection<T> as shown below, then enumeration will work.

        [ReaderWriterSynchronized]
        public class AbstractItemGroup : AdvisableCollection<Item>
        {
        }
    
        public class ItemGroup : AbstractItemGroup
        {
            public ItemGroup()
            {
                this.Add(new Item());
                this.Add(new Item());
            }
        }
    
        public interface IItem { }
    
        public class Item : IItem { }
    

    -alex

  4. 4 Posted by michael.proepst... on 12 Dec, 2017 02:00 PM

    michael.proepster's Avatar

    thank you for the hint

  5. michael.proepster closed this discussion on 12 Dec, 2017 02:00 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac