use*_*851 1 c# multithreading asynchronous task-parallel-library async-await
我有一个 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.
}
Run Code Online (Sandbox Code Playgroud)
因此,正如上面代码中提到的,当我打开时,PringDialogForm它会打开一个进度栏表单来查看打印文档的进度,从这里frmExportSearchResultsProgress_Shown()触发事件并在其中调用该方法,DoDataItemPrint()该方法非常耗时。因此,我尝试将frmExportSearchResultsProgress_Shown事件设为async/await但操作仍然花费与之前相同的时间。
谁能建议我哪里做错了?
frmExportSearchResultsProgress_Shown方法在 UI 线程上启动DoDataItemPrint到...相同的 UI 线程await),以便当不完整的事情发生时,我们回到frmExportSearchResultsProgress_Shown,并且由于这里可能有一个同步上下文,同步上下文捕获(隐式在 中await)会将我们推向... UI线正如你所看到的:一切都发生在 UI 线程上。
如果不想阻塞UI,就需要脱离UI线程。这可能就像使用Task.Runinvoke一样简单DoDataItemPrint,但是如果不知道该代码包含什么内容,就不可能知道您是否正在使用线程绑定控件来进行打印。如果你是……就很难摆脱这一点。
| 归档时间: |
|
| 查看次数: |
99 次 |
| 最近记录: |