简体   繁体   English

为什么async await操作还是很耗时

[英]Why async await operation is still time consuming

I have a Winforms application where I am trying to print a pdf document which has multiple layers on it.我有一个 Winforms 应用程序,我正在尝试打印一个 pdf 文档,该文档上面有多个图层。 But the problem is, This all operation are running on UI thread and it is hanging the UI(not responding) for long time.但问题是,所有操作都在 UI 线程上运行,并且长时间挂起 UI(未响应)。 I know, this is happening because of UI thread is blocked so, I have tried to make this operation asynchronous by the help of powerful async/await keyword but still my long running method is not being asynchronous.我知道,这是因为 UI 线程被阻塞而发生的,所以我试图借助强大的async/await关键字使这个操作异步,但我的长期运行方法仍然不是异步的。 It is not coming forward from the await tasks and still opearation is taking the same time as like synchronous operation.它不是从await任务中取得进展,并且仍然与同步操作一样花费相同的时间。

What I tried:我尝试了什么:

Please see below:请看下面:

/// <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.
  }

So, as per mentioned in above code when I opened the PringDialogForm then it is opening a Progress Bar form to see the progress of printing the document and from here frmExportSearchResultsProgress_Shown() event is fired and inside it, I am calling the DoDataItemPrint() method which is time consuming.因此,正如上面代码中提到的,当我打开PringDialogForm时,它会打开一个进度条表单以查看打印文档的进度,并从这里frmExportSearchResultsProgress_Shown()事件并在其中调用DoDataItemPrint()方法这很耗时。 So, I tried to make frmExportSearchResultsProgress_Shown event as async/await but still operation is taking the same time as previous.因此,我尝试将frmExportSearchResultsProgress_Shown事件设置为async/await ,但操作仍与之前的时间相同。

Can anyone please suggest me where I am doing wrong?谁能建议我哪里做错了?

  • your frmExportSearchResultsProgress_Shown method starts on the UI thread您的frmExportSearchResultsProgress_Shown方法在 UI 线程上启动
  • it then dispatches DoDataItemPrint to the... same UI thread然后DoDataItemPrint分派到...相同的 UI 线程
  • it schedules a continuation (via await ) so that when that incomplete thing happens, we get back into frmExportSearchResultsProgress_Shown , and since there's probably a sync-context in play here, the sync-context capture (implicit in await ) would push us to... the UI thread它安排了一个延续(通过await ),以便当那个不完整的事情发生时,我们回到frmExportSearchResultsProgress_Shown ,并且由于这里可能有一个同步上下文在起作用,同步上下文捕获(隐含在await中)将推动我们...... . 界面线程

As you can see: everything is happening on the UI thread .如您所见:一切都发生在 UI 线程上

If you want to not block the UI, you need to get off the UI thread .如果你不想阻塞 UI,你需要离开 UI 线程 That could be as simple as using Task.Run to invoke DoDataItemPrint , but without knowing what that code contains, it is impossible to know whether you're using thread-bound controls to do the printing.这可能与使用Task.Run调用DoDataItemPrint一样简单,但不知道该代码包含什么,就不可能知道您是否正在使用线程绑定控件进行打印。 If you are... it will be hard to get away from that.如果你是……就很难摆脱它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM