codeproject / CodeProject.AI-Server

CodeProject.AI Server is a self contained service that software developers can include in, and distribute with, their applications in order to augment their apps with the power of AI.
https://codeproject.github.io/codeproject.ai
Other
721 stars 159 forks source link

CodeProject.AI.Explorer .NET demo crashes because of incorrect use of ConfigureAwait() #63

Closed matra774 closed 1 year ago

matra774 commented 1 year ago

Area of Concern

Describe the bug After selecting an image and clicking When clicking "Detect X" button it CodeProject.AI.Explorer .NET it crases synchronisation exception:

System.Reflection.TargetInvocationException
  HResult=0x80131604
  Message=Exception has been thrown by the target of an invocation.
  Source=System.Private.CoreLib
  StackTrace:
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
   at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Forms.Control.InvokeMarshaledCallbacks()
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, WM msg, IntPtr wparam, IntPtr lparam)
   at Interop.User32.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.Interop.Mso.IMsoComponentManager.FPushMessageLoop(UIntPtr dwComponentID, msoloop uReason, Void* pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(msoloop reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(msoloop reason, ApplicationContext context)
   at CodeProject.AI.Demo.Explorer.Program.Main() in C:\src\CodeProject.AI-Server\demos\dotNet\CodeProject.AI.Explorer\Program.cs:line 18

  This exception was originally thrown at this call stack:
    System.Windows.Forms.Control.Handle.get()
    Interop.User32.SetWindowTextW(IHandle, string)
    System.Windows.Forms.Control.WindowText.set(string)
    System.Windows.Forms.TextBoxBase.WindowText.set(string)
    System.Windows.Forms.Control.Text.set(string)
    System.Windows.Forms.TextBoxBase.Text.set(string)
    System.Windows.Forms.TextBox.Text.set(string)
    CodeProject.AI.Demo.Explorer.Form1.DetectFaceBtn_Click(object, System.EventArgs) in Form1.cs
    System.Threading.Tasks.Task.ThrowAsync.AnonymousMethod__128_0(object)

Inner Exception 1:
InvalidOperationException: Cross-thread operation not valid: Control 'detectionResult' accessed from a thread other than the thread it was created on.

Expected behavior Shouldn't crash.

Screenshots NA

Your System (please complete the following information):

Additional context The sample code uses .ConfigureAwait(false), which explicitly allows continuation to be executed on another context, which is not OK, since WinForms requires GUI updates to be done from the ame thread that crated controls.

Solution: force execution is same context. Example:

var result = await _AIService.DetectFaces(_imageFileName).ConfigureAwait(true); // change false to true or omit ConfigureAwait() call
ChrisMaunder commented 1 year ago

This has been fixed