I have a Winforms application where I am trying to print a pdf document which has multiple layers on it. But the problem is, This all operation are running on UI thread and it is hanging the UI(not responding) for long time. 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. It is not coming forward from the await tasks and still opearation is taking the same time as like synchronous operation.
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. So, I tried to make frmExportSearchResultsProgress_Shown event as async/await but still operation is taking the same time as previous.
Can anyone please suggest me where I am doing wrong?
Application.DoEvents(). It is evil. It is only in the framework for compatibility with VB6 from 2001. It can cause re-entrancy issues and even lock up your UI. You should remove it immediately.