C# 我可以用不同的线程过滤来自窗口的消息吗?

C# 我可以用不同的线程过滤来自窗口的消息吗?,c#,windows,multithreading,messages,C#,Windows,Multithreading,Messages,我正在编写一个使用TwainDotNet进行扫描的应用程序 一切正常,但扫描会使用户界面无法使用。所以我决定在另一个线程中扫描,但我从未获得扫描成功事件。因此,我决定仔细研究一下实施情况: 公共数据源管理器(身份应用程序ID、, IWindowsMessageHook(消息钩子) { //制作标识的副本,以防其被修改 ApplicationId=ApplicationId.Clone(); ScanningComplete+=委托{}; TransferImage+=委托{}; _message

我正在编写一个使用TwainDotNet进行扫描的应用程序

一切正常,但扫描会使用户界面无法使用。所以我决定在另一个线程中扫描,但我从未获得扫描成功事件。因此,我决定仔细研究一下实施情况:

公共数据源管理器(身份应用程序ID、,
IWindowsMessageHook(消息钩子)
{
//制作标识的副本,以防其被修改
ApplicationId=ApplicationId.Clone();
ScanningComplete+=委托{};
TransferImage+=委托{};
_messageHook=messageHook;
_messageHook.FilterMessageCallback=FilterMessage;
IntPtr windowHandle=\u messageHook.windowHandle;
_eventMessage.EventPtr=
AllocHGlobal(Marshal.SizeOf(typeof(WindowsMessage));
以及进行过滤的方法:

受保护的IntPtr筛选器消息(IntPtr hwnd、int msg、IntPtr wParam、,
IntPtr LPRAM,参考布尔处理)
{
通常这种方法会过滤消息日志,但如果我在另一个线程中扫描,则不会收到任何消息

我的代码的扫描部分是:

var scanningThread=新线程((ThreadStart)委托
{
//以前我在这里得到了主UI表单,但这也不起作用
var form=new form();
var messageHook=newwinformswindowmessagehook(form.Handle);
var scanner=新TwainEngine(messageHook);
scanner.TransferImage+=TransferImage;
scanner.ScanningComplete+=扫描完成;
扫描仪。开始扫描(TWAINSETINGS设置);
});
scanningThread.Start();

我对Win32消息体系结构一无所知,因此有关如何解决此问题或导致此问题的原因的任何输入都会有所帮助。

由于您在没有消息循环的线程上创建表单,因此您拥有的代码将无法正常工作。如果此库确实需要表单或消息循环,并且正在挂起U然后,除了它有设计问题,这可能是一个非常罕见的情况下,你可能要考虑有一个第二个线程运行消息循环。 要创建运行消息循环的线程,请使用
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
来封送委托的执行。

伙计,您走错了方向。不要在其他线程上创建表单。未显示的表单句柄也会出现thless.你确定你在等待扫描完成时没有阻塞GUI吗?@Brannon:谢谢你的回复。我确定我没有阻塞任何东西。库附带的演示程序也有同样的问题。非常感谢你的回复。我会在有时间的时候尝试。非常感谢,我修改了它以隐藏表单并在之后关闭它扫描完成。