Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Would this be a valid Extension?

Would this be a valid Extension?

Scheduled Pinned Locked Moved C#
question
6 Posts 3 Posters 45 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    charles henington
    wrote on last edited by
    #1

    using locks, from my understanding this should work as long as lock is being called on the same object.

    internal static async Task Lock(this T lockObject, Action DoAction) where T : class
    {
    await Task.Run(() => { lock(lockObject)
    {
    DoAction();
    }});
    }

    P Richard DeemingR 2 Replies Last reply
    0
    • C charles henington

      using locks, from my understanding this should work as long as lock is being called on the same object.

      internal static async Task Lock(this T lockObject, Action DoAction) where T : class
      {
      await Task.Run(() => { lock(lockObject)
      {
      DoAction();
      }});
      }

      P Offline
      P Offline
      Pete OHanlon
      wrote on last edited by
      #2

      From what I can see, the code you've provided isn't going to achieve what you might expect it to achieve. I'm going to break the logic down so you can see where the confusion lies.

      1. The await operator here does not appear to affect the locking behaviour. It's only waiting for the Task.Run to complete.
      2. Inside the Task.Run, we have a lock statement. You can think of this as running on a different thread from the caller.
      3. Each call to this method will create a new task, which will attempt to acquire the lock independently.

      The end result is multiple calls to this method could run concurrently, each in its own task, defeating the purpose of the lock. The lock will still work within each individual task, but it won't prevent multiple tasks from running simultaneously. To my mind, a better version of this would be this:

      private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);

      internal static async Task Lock(this T lockObject, Action DoAction) where T : class
      {
      try
      {
      await _semaphore.WaitAsync();
      DoAction();
      }
      finally
      {
      _semaphore.Release();
      }
      }

      Advanced TypeScript Programming Projects

      C 1 Reply Last reply
      0
      • C charles henington

        using locks, from my understanding this should work as long as lock is being called on the same object.

        internal static async Task Lock(this T lockObject, Action DoAction) where T : class
        {
        await Task.Run(() => { lock(lockObject)
        {
        DoAction();
        }});
        }

        Richard DeemingR Offline
        Richard DeemingR Offline
        Richard Deeming
        wrote on last edited by
        #3

        From what I can see, it should work. Whilst held, the lock prevents any other thread from obtaining the lock. And the thread that's holding the lock never* yields, so nothing else can be run on the same thread. (* Assuming DoAction doesn't do anything odd, such as point to an async void method.) But wouldn't it be better to use a proper async-friendly lock instead? Building Async Coordination Primitives, Part 6: AsyncLock - .NET Parallel Programming[^]


        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

        "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

        C 2 Replies Last reply
        0
        • Richard DeemingR Richard Deeming

          From what I can see, it should work. Whilst held, the lock prevents any other thread from obtaining the lock. And the thread that's holding the lock never* yields, so nothing else can be run on the same thread. (* Assuming DoAction doesn't do anything odd, such as point to an async void method.) But wouldn't it be better to use a proper async-friendly lock instead? Building Async Coordination Primitives, Part 6: AsyncLock - .NET Parallel Programming[^]


          "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

          C Offline
          C Offline
          charles henington
          wrote on last edited by
          #4

          Within the DoAction() it performs read/write operations on a memory pointer

          1 Reply Last reply
          0
          • Richard DeemingR Richard Deeming

            From what I can see, it should work. Whilst held, the lock prevents any other thread from obtaining the lock. And the thread that's holding the lock never* yields, so nothing else can be run on the same thread. (* Assuming DoAction doesn't do anything odd, such as point to an async void method.) But wouldn't it be better to use a proper async-friendly lock instead? Building Async Coordination Primitives, Part 6: AsyncLock - .NET Parallel Programming[^]


            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

            C Offline
            C Offline
            charles henington
            wrote on last edited by
            #5

            This is how the lock is being used.

            public async Task GetSamples()
            {
            if (!ContainsAudio())
            throw new ArgumentException(nameof(G711.Alaw));
            short[] samples = [];
            NativePointer pointer = _nativePointer!;
            await pointer.Lock(() =>
            {
            unsafe
            {
            var sampleCount = pointer.Size >> 1;
            samples = new short[sampleCount];
            var memoryBlock = pointer.GetMemoryBlock();
            var value = (short*)memoryBlock;
            for (var i = 0; i < sampleCount; i++)
            {
            samples[i] = *value++;
            }
            }
            });
            return samples;
            }

            1 Reply Last reply
            0
            • P Pete OHanlon

              From what I can see, the code you've provided isn't going to achieve what you might expect it to achieve. I'm going to break the logic down so you can see where the confusion lies.

              1. The await operator here does not appear to affect the locking behaviour. It's only waiting for the Task.Run to complete.
              2. Inside the Task.Run, we have a lock statement. You can think of this as running on a different thread from the caller.
              3. Each call to this method will create a new task, which will attempt to acquire the lock independently.

              The end result is multiple calls to this method could run concurrently, each in its own task, defeating the purpose of the lock. The lock will still work within each individual task, but it won't prevent multiple tasks from running simultaneously. To my mind, a better version of this would be this:

              private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);

              internal static async Task Lock(this T lockObject, Action DoAction) where T : class
              {
              try
              {
              await _semaphore.WaitAsync();
              DoAction();
              }
              finally
              {
              _semaphore.Release();
              }
              }

              Advanced TypeScript Programming Projects

              C Offline
              C Offline
              charles henington
              wrote on last edited by
              #6

              Thanks for the hint on the using the SemaphoreSlim. This works much better than the original extension I was using.

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups