//--------------------------------------------------------------------------------------- // This code follows the architecture drawn by DotNetBrowser // (cf https://dotnetbrowser.support.teamdev.com/support/solutions/articles/9000109868-calling-javascript-from-net) // For an example of implementation, go to INTERNAL_InteropImplementation.cs and // ExecuteJavaScript_SimulatorImplementation method, in the first "if". //--------------------------------------------------------------------------------------- #if OPENSILVER private static object OnCallbackFromJavaScript <T>( int callbackId, string idWhereCallbackArgsAreStored, T callbackArgsObject, Func <int, int, string, T, Type[], object[]> makeArguments, bool isInSimulator, bool returnValue) { object result = null; var actionExecuted = false; Action action = () => { INTERNAL_SimulatorExecuteJavaScript.RunActionThenExecutePendingAsyncJSCodeExecutedDuringThatAction( () => { //-------------------- // Call the callback: //-------------------- try { result = CallMethod(callbackId, idWhereCallbackArgsAreStored, makeArguments, callbackArgsObject); actionExecuted = true; } catch (Exception ex) { #if DEBUG Console.Error.WriteLine("DEBUG: OnCallBack: OnCallBackFromJavascript: " + ex); #endif throw; } }); }; if (isInSimulator) { // Go back to the UI thread because DotNetBrowser calls the callback from the socket background thread: if (returnValue) { var timeout = TimeSpan.FromSeconds(30); INTERNAL_Simulator.WebControlDispatcherInvoke(action, timeout); if (!actionExecuted) { GenerateDeadlockException(timeout); } } else { INTERNAL_Simulator.WebControlDispatcherBeginInvoke(action); } } else { action(); } return(returnValue ? result : null); }
static void BeginInvokeInternal(Action method) { #if CSHTML5NETSTANDARD //Console.WriteLine("ON BEGININVOKE CALLED"); if (!INTERNAL_Simulator.IsRunningInTheSimulator_WorkAround) { // While running unit tests, we do not call Cshtml5Initializer.Initialize. // We just run the code synchronously in that case. if (INTERNAL_Simulator.JavaScriptExecutionHandler == null) { method(); return; } CSHTML5.Interop.ExecuteJavaScriptAsync("setTimeout($0, 1)", (Action)(() => { try { method(); } catch (Exception e) { Console.Error.WriteLine("DEBUG: CoreDispatcher: BeginIvokeInternal: Method excution failed: " + e); } })); } else { #endif //Simulator only. We call the JavaScript "setTimeout" to queue the action on the thread, and then we call Dispatcher.BeginInvoke(...) to ensure that it runs in the UI thread. //CSHTML5.Interop.ExecuteJavaScriptAsync("setTimeout($0, 1)", // (Action)(() => // { INTERNAL_Simulator.WebControlDispatcherBeginInvoke(method); //})); #if CSHTML5NETSTANDARD } #endif // Note: the implementation below was commented because it led to issues when drawing the Shape controls: sometimes some Shape controls did not render in the Simulator because the method passed "Dispatcher.Begin()" was called too early. /* * global::System.Threading.Timer timer = new global::System.Threading.Timer( * delegate(object state) * { * INTERNAL_Simulator.WebControl.Dispatcher.BeginInvoke((Action)(() => * { * method(); * })); * }, * null, * 1, * global::System.Threading.Timeout.Infinite); */ }
public static void OnCallbackFromJavaScriptError(string idWhereCallbackArgsAreStored) { Action action = () => { string errorMessage = Convert.ToString(Interop.ExecuteJavaScript("document.jsObjRef[$0][0]", idWhereCallbackArgsAreStored)); int indexOfNextUnmodifiedJSCallInList = Convert.ToInt32(Interop.ExecuteJavaScript("document.jsObjRef[$0][1]", idWhereCallbackArgsAreStored)); INTERNAL_InteropImplementation.ShowErrorMessage(errorMessage, indexOfNextUnmodifiedJSCallInList); }; #if OPENSILVER if (Interop.IsRunningInTheSimulator_WorkAround) #else if (Interop.IsRunningInTheSimulator) #endif { // Go back to the UI thread because DotNetBrowser calls the callback from the socket background thread: INTERNAL_Simulator.WebControlDispatcherBeginInvoke(action); } else { action(); } }
public void OnCallbackFromJavaScript( int callbackId, string idWhereCallbackArgsAreStored, JSArray callbackArgsObject ) { Action action = () => { //---------------------------------- // Get the C# callback from its ID: //---------------------------------- Delegate callback = _dictionary[callbackId]; //#if CSHTML5NETSTANDARD // try // { // Console.WriteLine( // "CallbackID: " + callbackId.ToString() + "\n" + // "Callback Method Name: " + callback.Method.Name + "\n" + // "Callback Method Body: " + callback.Method.GetMethodBody().ToString() + "\n" + // "Callback Target: " + callback.Target.ToString() + "\n" + // "idWhereCallbackArgsAreStored: " + idWhereCallbackArgsAreStored.ToString() + "\n" + // "Dictionary.Count: " + _dictionary.Count.ToString()); // } // catch (Exception e) // { // } //#endif Type callbackType = callback.GetType(); Type[] callbackGenericArgs = null; if (callbackType.IsGenericType) { callbackGenericArgs = callbackType.GetGenericArguments(); callbackType = callbackType.GetGenericTypeDefinition(); } var callbackArgs = callbackArgsObject; //-------------------- // Call the callback: //-------------------- #if CATCH_INTEROP_EXCEPTIONS // Note: previously, when using the "Awesomium" browser control in the Simulator, we handled the exceptions because otherwise they got captured by the WebBrowser control, due to the fact that the callback is executed in the context of the WebBrowser control. This is no longer true with the "DotNetBrowser" control. try { #endif try { if (callbackType == typeof(Action)) { DelegateDynamicInvoke(callback); } else if (callbackType == typeof(Action <>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(1, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(2, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(3, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(4, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(5, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(6, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(7, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(8, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(9, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else { throw new Exception(string.Format("Callback type not supported: {0} Please report this issue to [email protected]", callbackType.ToString())); } } catch (global::System.Reflection.TargetInvocationException ex) { if (global::System.Diagnostics.Debugger.IsAttached) { if (ex.InnerException != null) { // We rethrow the inner exception if any, that is, the exception that happens in the C# code being called by "DynamicInvoke". cf. https://stackoverflow.com/questions/57383/in-c-how-can-i-rethrow-innerexception-without-losing-stack-trace INTERNAL_Simulator.SimulatorProxy.ThrowExceptionWithoutLosingStackTrace(ex.InnerException); } else { throw; } } else { INTERNAL_Simulator.SimulatorProxy.ShowException(ex.InnerException ?? ex); } } #if CATCH_INTEROP_EXCEPTIONS // Note: previously, when using the "Awesomium" browser control in the Simulator, we handled the exceptions because otherwise they got captured by the WebBrowser control, due to the fact that the callback is executed in the context of the WebBrowser control. This is no longer true with the "DotNetBrowser" control. } catch (Exception ex) // We catch and handle the Exception because otherwise it gets captured by the WebBrowser control, due to the fact that the callback is executed in the context of the WebBrowser control. { string message = ex.Message; if (Interop.IsRunningInTheSimulator && ex.InnerException != null) // Note: "InnerException" is only supported in the Simulator as of July 27, 2017. { message += Environment.NewLine + Environment.NewLine + ex.InnerException.Message + Environment.NewLine + Environment.NewLine + ex.InnerException.StackTrace; } else { message += Environment.NewLine + Environment.NewLine + ex.StackTrace; } if (Interop.IsRunningInTheSimulator) { // Go back to the UI thread because DotNetBrowser calls the callback from the socket background thread: INTERNAL_Simulator.WebControl.Dispatcher.BeginInvoke((Action)(() => { MessageBox.Show(message); })); } else { MessageBox.Show(message); } } #endif }; if (Interop.IsRunningInTheSimulator) { // Go back to the UI thread because DotNetBrowser calls the callback from the socket background thread: INTERNAL_Simulator.WebControlDispatcherBeginInvoke(action); } else { action(); } }
internal static void ExecuteJavaScriptAsync(string javaScriptToExecute, string commentForDebugging = null) { if (EnableInteropLogging) { AddCommentsForDebuggingIfAny(ref javaScriptToExecute, commentForDebugging); } if (!_disableAsyncJavaScriptExecution) { //-------------------------------------------------------- // Note: since we moved from the "Awesomium" control to the "DotNetBrowser" control // for rending the HTML in the WPF-based Simulator, we have stopped using the // "ExecuteJavaScriptAsync" method provided by the browser control, because it // causes DotNetBrowser to freeze (cf. the email conversation with DotNetBrowser // support in December 2017). // Instead, what we do is that we postpone the execution of the JS code that does // not return any value (we do that by calling the "Dispatcher.BeginInvoke" method), // and aggregate them in order to reduce the number of interop JS calls from C#. // This significantly improves performance. //-------------------------------------------------------- lock (_pendingAsyncJavaScriptToExecute) { _pendingAsyncJavaScriptToExecute.Add(javaScriptToExecute); } #if !CSHTML5NETSTANDARD if (!_isDispatcherPending) { _isDispatcherPending = true; INTERNAL_Simulator.WebControlDispatcherBeginInvoke((Action)(() => { if (_isDispatcherPending) // We check again, because in the meantime the dispatcher can be cancelled in case of a forced execution of the pending JS code, for example when making a JavaScript execution that "returns a value". { ExecutePendingJavaScriptCode("BEGININVOKE COMPLETED"); } })); } #else if (_isInsideMethodToRunAnActionAndThenExecuteItsPendingJS) { #if OPTIMIZATION_LOG Console.WriteLine("[OPTIMIZATION] Add to pending JS code (" + _pendingAsyncJavaScriptToExecute.Count.ToString() + ")"); #endif //-------------------------------------------------------- // Nothing else to do here: the pending JS code will get executed when the thread is free, thanks // to the fact that we always call "EnsurePendingAsyncJavaScriptGetFlushedAfterExecutingThisAction" // before execute any piece of C# code (ie. at all the entry points of C#, such as when the app // starts, and in the callbacks from JavaScript). //-------------------------------------------------------- } else { //-------------------------------------------------------- // We may arrive here is there is an "async" method that is not awaited and for example that contains // "await Task.Delay(...)", which means that the code will resume without being "wrapped" inside a // call to "RunActionThenExecutePendingAsyncJSCodeExecutedDuringThatAction". In this case we use // the setTimeout method to ensure that the Flush is always executed. //-------------------------------------------------------- #if OPTIMIZATION_LOG Console.WriteLine("[OPTIMIZATION] Direct execution of code. _isDispatcherPending: " + _isDispatcherPending.ToString()); #endif if (!_isDispatcherPending) { _isDispatcherPending = true; #if OPTIMIZATION_LOG Console.WriteLine("[OPTIMIZATION] Calling setTimeout. _isDispatcherPending: " + _isDispatcherPending.ToString()); #endif CSHTML5.INTERNAL_InteropImplementation.ExecuteJavaScript_SimulatorImplementation( javascript: "setTimeout($0, 1)", runAsynchronously: false, noImpactOnPendingJSCode: true, variables: new object[] { (Action)(() => { #if OPTIMIZATION_LOG Console.WriteLine("[OPTIMIZATION] Executing setTimeout. _isDispatcherPending: " + _isDispatcherPending.ToString()); #endif if (_isDispatcherPending) // We check again, because in the meantime the dispatcher can be cancelled in case of a forced execution of the pending JS code, for example when making a JavaScript execution that "returns a value". { ExecutePendingJavaScriptCode("SETTIMEOUT COMPLETED"); } }) } ); } } #endif } else { #if OPTIMIZATION_LOG Console.WriteLine("[OPTIMIZATION] Direct call"); #endif PerformActualInteropCall(javaScriptToExecute, "ASYNC DISABLED"); } }
public object OnCallbackFromJavaScript( int callbackId, string idWhereCallbackArgsAreStored, JSArray callbackArgsObject, bool returnValue) { object result = null; var actionExecuted = false; Action action = () => { //-------------------- // Call the callback: //-------------------- try { result = CallMethod(callbackId, idWhereCallbackArgsAreStored, MakeArgumentsForCallback, callbackArgsObject); actionExecuted = true; } catch (global::System.Reflection.TargetInvocationException ex) { if (global::System.Diagnostics.Debugger.IsAttached) { if (ex.InnerException != null) { // We rethrow the inner exception if any, that is, the exception that happens in the C# code being called by "DynamicInvoke". cf. https://stackoverflow.com/questions/57383/in-c-how-can-i-rethrow-innerexception-without-losing-stack-trace INTERNAL_Simulator.SimulatorProxy.ThrowExceptionWithoutLosingStackTrace(ex.InnerException); } else { throw; } } else { INTERNAL_Simulator.SimulatorProxy.ShowException(ex.InnerException ?? ex); } } }; if (Interop.IsRunningInTheSimulator) { // Go back to the UI thread because DotNetBrowser calls the callback from the socket background thread: if (returnValue) { var timeout = TimeSpan.FromSeconds(30); INTERNAL_Simulator.WebControlDispatcherInvoke(action, timeout); if (!actionExecuted) { GenerateDeadlockException(timeout); } } else { INTERNAL_Simulator.WebControlDispatcherBeginInvoke(action); } } else { action(); } return(result); }
public static void OnCallbackFromJavaScript( int callbackId, string idWhereCallbackArgsAreStored, object callbackArgsObject ) { Action action = () => { //---------------------------------- // Get the C# callback from its ID: //---------------------------------- Delegate callback = _dictionary[callbackId]; Type callbackType = callback.GetType(); Type[] callbackGenericArgs = null; if (callbackType.IsGenericType) { callbackGenericArgs = callbackType.GetGenericArguments(); callbackType = callbackType.GetGenericTypeDefinition(); } var callbackArgs = callbackArgsObject; //-------------------- // Call the callback: //-------------------- #if CATCH_INTEROP_EXCEPTIONS // Note: previously, when using the "Awesomium" browser control in the Simulator, we handled the exceptions because otherwise they got captured by the WebBrowser control, due to the fact that the callback is executed in the context of the WebBrowser control. This is no longer true with the "DotNetBrowser" control. try { #endif try { if (callbackType == typeof(Action)) { DelegateDynamicInvoke(callback); } else if (callbackType == typeof(Action <>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(1, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(2, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(3, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(4, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(5, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(6, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(7, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(8, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(9, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else { throw new Exception(string.Format("Callback type not supported: {0} Please report this issue to [email protected]", callbackType.ToString())); } } catch (Exception ex) { #if DEBUG Console.Error.WriteLine("DEBUG: OnCallBack: OnCallBackFromJavascript: " + ex); #endif throw; } #if CATCH_INTEROP_EXCEPTIONS // Note: previously, when using the "Awesomium" browser control in the Simulator, we handled the exceptions because otherwise they got captured by the WebBrowser control, due to the fact that the callback is executed in the context of the WebBrowser control. This is no longer true with the "DotNetBrowser" control. } catch (Exception ex) // We catch and handle the Exception because otherwise it gets captured by the WebBrowser control, due to the fact that the callback is executed in the context of the WebBrowser control. { string message = ex.Message; if (Interop.IsRunningInTheSimulator && ex.InnerException != null) // Note: "InnerException" is only supported in the Simulator as of July 27, 2017. { message += Environment.NewLine + Environment.NewLine + ex.InnerException.Message + Environment.NewLine + Environment.NewLine + ex.InnerException.StackTrace; } else { message += Environment.NewLine + Environment.NewLine + ex.StackTrace; } if (Interop.IsRunningInTheSimulator) { // Go back to the UI thread because DotNetBrowser calls the callback from the socket background thread: INTERNAL_Simulator.WebControl.Dispatcher.BeginInvoke((Action)(() => { MessageBox.Show(message); })); } else { MessageBox.Show(message); } } #endif }; if (Interop.IsRunningInTheSimulator_WorkAround) { // Go back to the UI thread because DotNetBrowser calls the callback from the socket background thread: INTERNAL_Simulator.WebControlDispatcherBeginInvoke(action); } else { action(); } }
public void OnCallbackFromJavaScript( int callbackId, string idWhereCallbackArgsAreStored, JSArray callbackArgsObject) { Action action = () => { //---------------------------------- // Get the C# callback from its ID: //---------------------------------- Delegate callback = _dictionary[callbackId]; Type callbackType = callback.GetType(); Type[] callbackGenericArgs = null; if (callbackType.IsGenericType) { callbackGenericArgs = callbackType.GetGenericArguments(); callbackType = callbackType.GetGenericTypeDefinition(); } var callbackArgs = callbackArgsObject; //-------------------- // Call the callback: //-------------------- try { if (callbackType == typeof(Action)) { DelegateDynamicInvoke(callback); } else if (callbackType == typeof(Action <>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(1, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(2, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(3, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(4, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(5, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(6, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(7, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(8, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(9, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else { throw new Exception(string.Format("Callback type not supported: {0} Please report this issue to [email protected]", callbackType.ToString())); } } catch (global::System.Reflection.TargetInvocationException ex) { if (global::System.Diagnostics.Debugger.IsAttached) { if (ex.InnerException != null) { // We rethrow the inner exception if any, that is, the exception that happens in the C# code being called by "DynamicInvoke". cf. https://stackoverflow.com/questions/57383/in-c-how-can-i-rethrow-innerexception-without-losing-stack-trace INTERNAL_Simulator.SimulatorProxy.ThrowExceptionWithoutLosingStackTrace(ex.InnerException); } else { throw; } } else { INTERNAL_Simulator.SimulatorProxy.ShowException(ex.InnerException ?? ex); } } }; if (Interop.IsRunningInTheSimulator) { // Go back to the UI thread because DotNetBrowser calls the callback from the socket background thread: INTERNAL_Simulator.WebControlDispatcherBeginInvoke(action); } else { action(); } }
public static void OnCallbackFromJavaScript( int callbackId, string idWhereCallbackArgsAreStored, object[] callbackArgsObject) { Action action = () => { INTERNAL_SimulatorExecuteJavaScript.RunActionThenExecutePendingAsyncJSCodeExecutedDuringThatAction( () => { //---------------------------------- // Get the C# callback from its ID: //---------------------------------- Delegate callback = _dictionary[callbackId]; Type callbackType = callback.GetType(); Type[] callbackGenericArgs = null; if (callbackType.IsGenericType) { callbackGenericArgs = callbackType.GetGenericArguments(); callbackType = callbackType.GetGenericTypeDefinition(); } var callbackArgs = callbackArgsObject; //-------------------- // Call the callback: //-------------------- try { if (callbackType == typeof(Action)) { DelegateDynamicInvoke(callback); } else if (callbackType == typeof(Action <>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(1, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(2, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(3, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(4, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(5, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(6, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(7, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(8, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else if (callbackType == typeof(Action <, , , , , , , ,>)) { DelegateDynamicInvoke(callback, MakeArgumentsForCallback(9, callbackId, idWhereCallbackArgsAreStored, callbackArgs, callbackGenericArgs)); } else { throw new Exception(string.Format("Callback type not supported: {0} Please report this issue to [email protected]", callbackType.ToString())); } } catch (Exception ex) { #if DEBUG Console.Error.WriteLine("DEBUG: OnCallBack: OnCallBackFromJavascript: " + ex); #endif throw; } }); }; if (Interop.IsRunningInTheSimulator_WorkAround) { // Go back to the UI thread because DotNetBrowser calls the callback from the socket background thread: INTERNAL_Simulator.WebControlDispatcherBeginInvoke(action); } else { action(); } }