diff --git a/samples/Sample.Console/Program.cs b/samples/Sample.Console/Program.cs index 92114cb..db49572 100644 --- a/samples/Sample.Console/Program.cs +++ b/samples/Sample.Console/Program.cs @@ -22,7 +22,14 @@ namespace Sample // just an amusing example to do twain in console without UI ThreadPool.QueueUserWorkItem(o => { - DoTwainWork(); + try + { + DoTwainWork(); + } + catch (Exception ex) + { + Console.WriteLine("ERROR: " + ex.ToString()); + } }); Console.WriteLine("Test started, press Enter to exit."); Console.ReadLine(); diff --git a/src/NTwain/Internals/InternalMessageLoopHook.cs b/src/NTwain/Internals/InternalMessageLoopHook.cs index 93aa1de..b0650d7 100644 --- a/src/NTwain/Internals/InternalMessageLoopHook.cs +++ b/src/NTwain/Internals/InternalMessageLoopHook.cs @@ -71,6 +71,8 @@ namespace NTwain.Internals { if (_dispatcher == null) { throw new InvalidOperationException(Resources.MsgLoopUnavailble); } + Exception error = null; + if (_dispatcher.CheckAccess()) { action(); @@ -85,6 +87,7 @@ namespace NTwain.Internals { action(); } + catch (Exception ex) { error = ex; } finally { man.Set(); @@ -95,8 +98,17 @@ namespace NTwain.Internals } else { - _dispatcher.Invoke(DispatcherPriority.Normal, action); + _dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => + { + try + { + action(); + } + catch (Exception ex) { error = ex; } + })); } + + if (error != null) { Rethrow(error); } } } } diff --git a/src/NTwain/MessageLoopHooks.cs b/src/NTwain/MessageLoopHooks.cs index 1e4a477..f91f619 100644 --- a/src/NTwain/MessageLoopHooks.cs +++ b/src/NTwain/MessageLoopHooks.cs @@ -1,5 +1,6 @@ using NTwain.Internals; using System; +using System.Reflection; using System.Threading; using System.Windows.Interop; @@ -47,13 +48,34 @@ namespace NTwain } else { + Exception error = null; SyncContext.Send(o => { - action(); + try + { + action(); + } + catch (Exception ex) + { + error = ex; + } }, null); + + if (error != null) { Rethrow(error); } } } + /// + /// Rethrows the specified excetion while keeping stack trace. + /// + /// The ex. + protected static void Rethrow(Exception ex) + { + typeof(Exception).GetMethod("PrepForRemoting", + BindingFlags.NonPublic | BindingFlags.Instance)?.Invoke(ex, new object[0]); + throw ex; + } + internal void ThrowInvalidOp() { throw new InvalidOperationException(InvalidMessage);