我正在编写一个使用TwainDotNet进行扫描的应用程序。
一切正常,但扫描会使用户界面不可用。所以我决定在另一个线程中扫描,但我从未获得扫描成功事件。所以我决定仔细看看它的实现:
public DataSourceManager(Identity applicationId,
IWindowsMessageHook messageHook)
{
// Make a copy of the identity in case it gets modified
ApplicationId = applicationId.Clone();
ScanningComplete += delegate { };
TransferImage += delegate { };
_messageHook = messageHook;
_messageHook.FilterMessageCallback = FilterMessage;
IntPtr windowHandle = _messageHook.WindowHandle;
_eventMessage.EventPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WindowsMessage)));以及执行过滤的方法:
protected IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam,
IntPtr lParam, ref bool handled)
{通常,此方法会过滤消息日志,但如果我在另一个线程中扫描,则不会收到任何消息。
我的代码的扫描部分是:
var scanningThread = new Thread((ThreadStart) delegate
{
// Previously I got the main UI form here, but that didn't work either
var form = new Form();
var messageHook = new WinFormsWindowMessageHook(form.Handle);
var scanner = new TwainEngine(messageHook);
scanner.TransferImage += TransferImage;
scanner.ScanningComplete += ScanningComplete;
scanner.StartScanning(twainSettings);
});
scanningThread.Start();我对Win32消息体系结构一无所知,所以任何关于我如何解决这个问题或者是什么导致这个问题的意见都会很有帮助。
发布于 2012-03-22 22:14:53
您拥有的代码将无法正常工作,因为您正在没有消息循环的线程上创建窗体。如果这个库确实需要一个表单或消息循环,并且它挂起了UI,那么除了它有设计问题之外,这可能是非常罕见的情况之一,您可能会考虑让第二个线程运行消息循环。
要创建运行消息循环的线程,请使用Application.Run。修改后的代码可能如下所示。
var scanningThread = new Thread((ThreadStart) delegate
{
var form = new Form();
form.Load += (sender, args) =>
{
var messageHook = new WinFormsWindowMessageHook(form.Handle);
var scanner = new TwainEngine(messageHook);
scanner.TransferImage += TransferImage;
scanner.ScanningComplete += ScanningComplete;
scanner.StartScanning(twainSettings);
};
Application.Run(form);
});
scanningThread.Start();我必须指出,拥有多个UI线程可能会导致一些奇怪的问题,因此通常不建议这样做。然而,就像我说的,你可能别无选择。另外,将这两个UI线程上发生的所有活动完全分开。不应尝试从此辅助UI线程访问在主UI线程上运行的UI控件。将会出现各种各样不可预测和引人注目的问题。如果需要强制在一个线程上执行某个操作,请使用Invoke或BeginInvoke来封送委托的执行。
https://stackoverflow.com/questions/9812346
复制相似问题