michielpost / Q42.HueApi

C# helper library to talk to the Philips Hue bridge
MIT License
411 stars 114 forks source link

SendCommandAsync occasionally throws ArgumentExceptions() #249

Closed mholubinka1 closed 3 years ago

mholubinka1 commented 3 years ago

Seems to be a race condition problem within SendCommandRawAsync.

   at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
   at System.Array.Copy(Array sourceArray, Array destinationArray, Int32 length)
   at System.Collections.Generic.List`1.set_Capacity(Int32 value)
   at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
   at System.Collections.Generic.List`1.AddWithResize(T item)
   at System.Collections.Generic.List`1.Add(T item)
   at Q42.HueApi.HueClient.<>c__DisplayClass20_0.<<SendCommandRawAsync>b__0>d.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
   at Q42.HueApi.Extensions.IEnumerableExtensions.<ProcessAsync>d__1`1.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
   at Q42.HueApi.HueClient.<SendCommandRawAsync>d__20.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at HueShift2.Control.LightManager.<Transition>d__10.MoveNext() in C:\Users\mehol\git\github\hueshift2\HueShift2\HueShift2\Control\LightManager.cs:line 120

I get an ArgumentExceptions() thrown (seemingly at random) saying "Source array was not long enough. Check the source index, length, and the array's lower bounds. (Parameter 'sourceArray')"

My executing code is this:

        await Refresh(currentTime);
        PrintScheduled();
        var commandLights = this.lights.SelectLightsToControl();
        logger.LogCommand(commandLights, target);
        var commandIds = commandLights.Select(x => x.Properties.Id).ToArray();
        if (commandIds.Length > 0) await client.SendCommandAsync(command, commandIds);

Making all my code synchronous, locking, etc... isn't solving it. Checking the source code HueResults isn't thread safe but is modified inside a parallelised Foreach within SendCommandRawAsync.

michielpost commented 3 years ago

Thanks for finding this issue! I fixed it with PR #250 I will do some more testing and then release it to NuGet.

michielpost commented 3 years ago

Fix is in version 3.18.1, now on NuGet