【问题标题】:C# WIA Transfer method locks UI threadC# WIA Transfer 方法锁定 UI 线程
【发布时间】:2014-03-24 17:04:18
【问题描述】:

我遇到了一个让我有些头疼的问题。 我有一个 Winform 应用程序,它向用户显示一个非常简单的对话框,只需一个按钮:“SCAN”。按钮的单击处理程序,您怎么能轻易想象,使用 WIA COM 对象启动扫描操作。 就代码而言,当按下按钮时,它会创建一个新的异步任务,该任务调用 Item 类的 Transfer 方法。 问题是 UI 线程会自行冻结,直到扫描结束,尽管扫描对象正在另一个线程上工作。 MSDN 上的文档说:

“Transfer 本质上是 ShowTransfer 的一个版本,它不显示 UI 或允许用户取消传输。”

所以我假设,“不显示 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);

这是调用 Transfer 的 Scan 方法的一部分:

var imageFile = (ImageFile) _item.Transfer(FormatID.wiaFormatTIFF);
var buffer = (byte[])imageFile.FileData.get_BinaryData();

return Image.FromStream(new MemoryStream(buffer)) as Bitmap;

我的假设是否正确? 在不使用 WIA 对话框的情况下如何避免这种行为?

注意:线程都在 STA 中

非常感谢您

【问题讨论】:

    标签: c# multithreading com wia


    【解决方案1】:

    当您创建新任务时,您传入一个使用TaskScheduler.FromCurrentSynchronizationContext(); 创建的TaskScheduler,这意味着代码将在 UI 线程中运行,而不是在另一个线程中运行。如果您不希望代码在 UI 线程中运行,则需要将代码编组到 UI 线程。

    【讨论】:

    • 等等,什么,TaskScheduler 编组整个线程?!从来不知道!
    • @aevitas 它定义了如何安排指定的任务。如果您提供一个调度程序,将所有在 UI 线程中运行的任务调度到一个新任务,它将在 UI 线程中运行。如果您提供一个执行其他操作的调度程序,它会执行其他操作。如果不提供,将使用默认值,即使用线程池。线程未编组。任务(或任何其他委托/操作)是被封送的。
    • 感谢您的解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多