-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
I'm seeing a parameter count mismatch exception from a System.Reflection usage of a Delegate - which is declared via a lambda expression:
public static class DialogEventHandlers
{
/// <summary>
/// Delegate for updating dialog progress. The parameters translate into the view model for the LoadingView.
/// </summary>
public delegate void DialogProgressHandler(int taskCount, int tasksComplete, int tasksError, string message);
}
await viewModelController.Initialize((taskCount, tasksComplete, tasksError, message) =>
{
// Code to call the Application Dispatcher was removed until this bug gets fixed.
});
The delegate "DialogProgressHandler" is passed through a tree of tasks, each using it and invoking it with the primitive arguments (thread safe) seen above. The fact that the instance of this delegate was produced using a lambda came to mind as there may be Task issues associated with sharing a delegate. However, it didn't seem to matter for other uses of the same TPL pattern.
The bug is seen when calling the handler - but not right away:
var artistCount = artistEntities.Count();
var artistIndex = 0;
// Load the album collection
foreach (var artist in artistEntities.OrderBy(x => x.Name))
{
// Progress Update
progressHandler.Invoke(artistCount, ++artistIndex, 0, "Loading Artists...");
}
The foreach loop above will execute several (hundred) times. After some (delayed execution) time, the exception is thrown without any explanation - already having (successfully??) called the delegate(!!!) Imagine that the below code (where execution calls back the UI) will run - except for some other delayed invoke(?!)
// (see DialogEventHandlers.cs)
await viewModelController.Initialize((taskCount, tasksComplete, tasksError, message) =>
{
// This code will execute properly; and even without the dispatcher invoke here - which
// also executes properly.
ApplicationHelpers.InvokeDispatcher(() =>
{
dialogViewModel.Progress = tasksComplete / (double)taskCount;
dialogViewModel.Message = message;
}, DispatcherPriority.Background);
});
Here is the Exception Stack:
at System.Reflection.MethodBaseInvoker.ThrowTargetParameterCountException() in System.Reflection\MethodBaseInvoker.cs:line 76
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) in System.Reflection\RuntimeMethodInfo.cs:line 567
at System.Delegate.DynamicInvokeImpl(Object[] args) in System\Delegate.cs:line 55
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in System.Threading\ExecutionContext.cs:line 138
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) in System.Threading\ExecutionContext.cs:line 153
at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at AudioStation.App.Main()
Reproduction Steps
(seen above)
Expected behavior
Handler should run synchronously - which it does - until some other unknown behavior in the .NET framework causes this exception.
Actual behavior
Parameter count mismatch is thrown.
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response