我有一個問題,這引起了我一些頭痛。 我有一個Winform應用程序,它顯示一個非常簡單的對話框,只有一個按鈕的用戶:「掃描」。按鈕的點擊處理程序,您怎麼能想象,使用WIA COM對象開始掃描操作。 就代碼而言,當按鈕按下時,它會創建一個新的異步Task,它調用Item類的Transfer方法。 問題是UI線程自行凍結,直到掃描結束,儘管掃描對象正在另一個線程上工作。 MSDN上的文檔說:C#WIA傳輸方法鎖UI線程
「傳輸本質上是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);
而且這是一個講求傳輸掃描方法的一部分:
var imageFile = (ImageFile) _item.Transfer(FormatID.wiaFormatTIFF);
var buffer = (byte[])imageFile.FileData.get_BinaryData();
return Image.FromStream(new MemoryStream(buffer)) as Bitmap;
是我的假設是否正確? 如何在不使用WIA對話框的情況下避免此行爲?
注:線程都在STA
非常感謝你提前
等一下,什麼'TaskScheduler'封送整個線程?!從未知道! – aevitas
@aevitas它定義了應如何安排指定的任務。如果您提供了一個調度程序,用於將UI線程中運行的所有任務調度爲新任務,它將在UI線程中運行。如果您提供了一個執行其他操作的調度程序,它將執行其他操作。如果您提供none,則將使用默認值,該值使用線程池。線程不封送。任務(或任何其他委託/操作)是編組的。 – Servy
感謝您的解釋! – aevitas