简体   繁体   English

通过c#.net代码打印pdf时出现线程问题?

[英]Threading issue while printing pdf through c#.net code?

I am trying to print pdf from windows application in my project with iTextSharp dll.. 我正在尝试使用iTextSharp dll从Windows应用程序中的Windows应用程序打印pdf。

But,The methods I have used till now doesn't seems to be reliable. 但是,我到目前为止使用的方法似乎并不可靠。 (Sometimes it work and sometime it doesn't) (有时它起作用,有时它不起作用)

I am combining the whole process in a Process class and writing the followin code. 我将整个过程组合在一个Process类中,并编写以下代码。

                            printProcess = new Process[noOfCopies];
 // Print number of copies specified in configuration file
                            for (int counter = 0; counter < noOfCopies; counter++)
                            {
                                printProcess[counter] = new Process();

                                // Set the process information
                                printProcess[counter].StartInfo = new ProcessStartInfo()
                                {
                                    CreateNoWindow = true,
                                    Verb = "Print",
                                    FileName = pdfFilePath,
                                    ErrorDialog = false,
                                    WindowStyle = ProcessWindowStyle.Hidden,
                                    UseShellExecute = true,
                                };


    // Start the printing process and wait for exit for 7 seconds
                                    printProcess[counter].Start();

                                    // printProcess[counter].WaitForInputIdle(waitTimeForPrintOut);
                                    printProcess[counter].WaitForExit(waitTimeForPrintOut); //<--**This is line for discussion**

                                    if (!printProcess[counter].HasExited)
                                    {
                                        printProcess[counter].Kill();
                                    }
                                }
   // Delete the file before showing any message for security reason
                        File.Delete(pdfFilePath);

The problem is that if,no pdf is open then the process works fine...(It prints well).But if any pdf is open then WaitForExit(..) method just doesn't waits for the process to exit..and hence the process runs too fast and as I am deleting the file after print it gives error if counter(no of times..) for printing report is more than once.. 问题是,如果没有打开pdf,则该进程运行良好...(它打印良好)。但是,如果打开了任何pdf,则WaitForExit(..)方法只是不等待该进程退出。因此,该过程运行得太快,并且在打印后删除文件时,如果打印报告的计数器(无次数)超过一次,则会出错。

I have also used Timer to slow the process but it just doesn't works.I don't know why. 我还使用了Timer来减慢该过程,但是它不起作用。我不知道为什么。 Used Sleep command too..but it makes main thread to go to sleep and hence doesn't suits me either. 也使用了Sleep命令..但是它使主线程进入睡眠状态,因此也不适合我。

Please suggest me some really reliable way to do so..:) 请建议我一些确实可靠的方法.. :)

I do not know what kind of application you are trying to print from but a real easy way to print documents or pdfs is to simply copy the file to the printer queue and it will handle everything for you. 我不知道您尝试从哪种类型的应用程序进行打印,但是一种打印文档或pdf的真正简便方法是将文件简单地复制到打印机队列中,它将为您处理所有事情。 Very reliable. 非常可靠。 Just have to have adobe reader installed on the machine printing and the correct driver for the printer. 只需在机器打印上安装Adobe Reader和正确的打印机驱动程序即可。 Example code: 示例代码:

        var printer = PrinterHelper.GetAllPrinters().FirstOrDefault(p => p.Default);
        PrinterHelper.SendFileToPrinter("C:\\Users\\Public\\Documents\\Form - Career Advancement Request.pdf", printer.Name);

Printer Helper code: 打印机助手代码:

    public static class PrinterHelper
    {
        public class PrinterSettings
        {
            public string Name { get; set; }
            public string ServerName { get; set; }
            public string DeviceId { get; set; }
            public string ShareName { get; set; }
            public string Comment { get; set; }
            public bool Default { get; set; }
        }

    /// <summary>
    /// Sends the file to printer.
    /// </summary>
    /// <param name="filePathAndName">Name of the file path and Name of File.</param>
    /// <param name="printerName">Name of the printer with Path. E.I. \\PRINT2.company.net\P14401</param>
        public static void SendFileToPrinter(string filePathAndName, string printerName)
        {
            FileInfo file = new FileInfo(filePathAndName);
            file.CopyTo(printerName);
        }

        /// <summary>
        /// Gets all printers that have drivers installed on the calling machine.
        /// </summary>
        /// <returns></returns>
        public static List<PrinterSettings> GetAllPrinters()
        {
            ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Printer");
            ManagementObjectSearcher mos = new ManagementObjectSearcher(query);
            List<PrinterSettings> printers = new List<PrinterSettings>();

            foreach (ManagementObject mo in mos.Get())
            {
                PrinterSettings printer = new PrinterSettings();
                foreach (PropertyData property in mo.Properties)
                {
                    if (property.Name == "Name")
                        printer.Name = property.Value == null ? "" : property.Value.ToString();

                    if (property.Name == "ServerName")
                        printer.ServerName = property.Value == null ? "" : property.Value.ToString();

                    if (property.Name == "DeviceId")
                        printer.DeviceId = property.Value == null ? "" : property.Value.ToString();

                    if (property.Name == "ShareName")
                        printer.ShareName = property.Value == null ? "" : property.Value.ToString();

                    if (property.Name == "Comment")
                        printer.Comment = property.Value == null ? "" : property.Value.ToString();

                    if (property.Name == "Default")
                        printer.Default = (bool)property.Value;
                }
                printers.Add(printer);
            }

            return printers;
        }      
}

Try this, you need .net 4 or above. 尝试此操作,您需要.net 4或更高版本。 And System.Threading.Tasks 和System.Threading.Tasks

  printProcess = new Process[noOfCopies];
  // Print number of copies specified in configuration file
  Parallel.For(0, noOfCopies, i =>
  {
    printProcess[i] = new Process();

    // Set the process information
    printProcess[i].StartInfo = new ProcessStartInfo()
    {
      CreateNoWindow = true,
      Verb = "Print",
      FileName = pdfFilePath,
      ErrorDialog = false,
      WindowStyle = ProcessWindowStyle.Hidden,
      UseShellExecute = true,
    };


    // Start the printing process and wait for exit for 7 seconds
    printProcess[i].Start();

    // printProcess[counter].WaitForInputIdle(waitTimeForPrintOut);
    printProcess[counter].WaitForExit(waitTimeForPrintOut); //<--**This is line for discussion**

    if(!printProcess[i].HasExited)
    {
      printProcess[i].Kill();
    }
  });
  // Delete the file before showing any message for security reason
  File.Delete(pdfFilePath);

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

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