我有一个让我头疼的问题。 我有一个Winform应用程序,只需一个按钮就可以向用户显示一个非常简单的对话框:" SCAN"。按钮的单击处理程序,您可以轻松想象,使用WIA COM对象启动扫描操作。 在代码方面,当按下按钮时,它会创建一个新的异步任务,它调用Item类的Transfer方法。 问题是UI线程冻结自己直到扫描结束,尽管扫描对象正在另一个线程上工作。 MSDN上的文档说:
"转移本质上是ShowTransfer的一个版本,它不显示用户界面或允许用户取消转移。"
所以我假设,句子"不显示UI",这意味着无论如何都会创建对话框,但它仍然是不可见的。然后,此对话框将自身挂钩到主线程(UI)并导致冻结(与模式对话框相同)。事实上,当我尝试使用ShowTransfer
方法时,它已经打开了对话框,但应用程序的UI线程并没有遭受冻结。
这是我的代码:
var progress = new Progress<string>(s => labelControl1.Text = s);
var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
var cancelSrc = new CancellationTokenSource();
await Task.Factory.StartNew(() => {
var facade = new ScanFacade();
facade.Scan(progress);
}, cancelSrc.Token, TaskCreationOptions.LongRunning, scheduler);
这是Scan方法的一部分,它调用Transfer:
var imageFile = (ImageFile) _item.Transfer(FormatID.wiaFormatTIFF);
var buffer = (byte[])imageFile.FileData.get_BinaryData();
return Image.FromStream(new MemoryStream(buffer)) as Bitmap;
我的假设是否正确? 如何在不使用WIA对话框的情况下避免此行为?
注意:线程都在STA
中非常感谢您提前
答案 0 :(得分:0)
创建新任务时,传入使用TaskScheduler
创建的TaskScheduler.FromCurrentSynchronizationContext();
,这意味着代码将在UI线程中运行,而不是在另一个线程中运行。如果您不希望它在UI线程中运行,则需要不将代码编组到UI线程。