Skip to content

Parameter Count Mismatch: when using a Delegate during an async / await call via a lambda expression #117867

@glowysourworm

Description

@glowysourworm

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

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIneeds-further-triageIssue has been initially triaged, but needs deeper consideration or reconsideration

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions