【发布时间】:2021-11-21 02:24:10
【问题描述】:
我有一个 Winforms 应用程序,我正在尝试打印一个上面有多个图层的 pdf 文档。
但问题是,所有操作都在 UI 线程上运行,并且长时间挂起 UI(无响应)。
我知道,这是因为 UI 线程被阻塞而发生的,所以我尝试借助强大的 async/await 关键字使此操作异步,但我的长期运行方法仍然不是异步的。它不是来自await 任务,并且操作与同步操作一样花费相同的时间。
我尝试了什么:
请看下面:
/// <summary>
/// Show Print Dialog
/// </summary>
private void ShowPrintDialog()
{
// Initialize print dialog
System.Windows.Controls.PrintDialog prtDialog = new System.Windows.Controls.PrintDialog();
prtDialog.PageRangeSelection = PageRangeSelection.AllPages;
prtDialog.UserPageRangeEnabled = false;
_printOptions.PrintQueue = null;
_printOptions.PrintTicket = null;
Enabled = false;
// if there is a default printer then set it
string defaulPrinter = prtDialog.PrintQueue == null ? string.Empty : prtDialog.PrintQueue.FullName;
// Display the dialog. This returns true if the user selects the Print button.
if (prtDialog.ShowDialog() == true)
{
_printOptions.PrintQueue = prtDialog.PrintQueue;
_printOptions.PrintTicket = prtDialog.PrintTicket;
_printOptions.UseDefaultPrinter = (defaulPrinter == prtDialog.PrintQueue.FullName);
}
// Re-enable the form
Enabled = true;
}
/// <summary>
/// Event raised when user clicks Print
/// </summary>
/// <param name="sender">Source of the event</param>
/// <param name="e">Event specific arguments</param>
private void cmdOk_Click(object sender, EventArgs e)
{
ShowPrintDialog();
if (_printOptions.PrintTicket != null)
{
//Set search Options
_print.ExportDataItem = true;
_print.FileName = SearchTemplateName;
//shows progress bar form.
using (frmPrintSearchResultsProgress frmProgress =
new frmPrintSearchResultsProgress(_print, this, _printOptions))
{
frmProgress.ShowDialog(this);
}
if (_print.ExportDataItem && !_print.DataItemExported && !_print.CancelExport)
{
MessageBox.Show("No Document printed.");
}
}
//Store selected options for current user
SaveOptions();
if (!SkipExport)
Close();
}
/// <summary>
/// Event raised when progress form is shown.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void frmExportSearchResultsProgress_Shown(object sender, EventArgs e)
{
try
{
Application.DoEvents();
dispatcher = Dispatcher.CurrentDispatcher;
// record export/print job start time
_startedUtc = DateTime.UtcNow;
_print.WritingToPdfIndicator = lblWritingPdfFile;
lblProgress.Text = Properties.Resources.PrintSearchResults;
await dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(DoDataItemPrint));
}
}
/// <summary>
/// Prints the selected data items.
/// </summary>
private void DoDataItemPrint()
{
// LONG RUNNING OPERATIONS..
// THIS OPERATION IS BLOCKING THE UI.
}
所以,正如上面代码中提到的,当我打开PringDialogForm 时,它正在打开一个进度条表单以查看打印文档的进度,并从这里触发frmExportSearchResultsProgress_Shown() 事件,在其中,我正在调用DoDataItemPrint() 方法很耗时。
所以,我尝试将frmExportSearchResultsProgress_Shown 事件设置为async/await,但仍然需要与之前相同的时间。
谁能告诉我哪里做错了?
【问题讨论】:
-
所有代码都在 UI 线程上运行。没有什么异步的
-
请删除
Application.DoEvents()。这是邪恶的。它仅在与 2001 年的 VB6 兼容的框架中。它可能会导致重入问题,甚至锁定您的 UI。您应该立即删除它。
标签: c# multithreading asynchronous async-await task-parallel-library