【问题标题】:How to run process in background? c#如何在后台运行进程? C#
【发布时间】:2014-08-30 16:16:27
【问题描述】:

我在我的应用程序中使用wkhtmltopdf 进行报告。但是它按预期工作得很好。

问题- 在下面的方法中,我将字符串源转换为 pdf 并写入字节。

注意- 在读取所有字节并尝试运行进程之前,我正在启动进程。 主要问题是运行此进程的后台能力。我没有让这个过程在后台运行。

目前发生的情况是在未生成 pdf 之前,整个应用程序进入暂停模式。这与后台进程无法正常工作有关。

如何修改此进程,使其在后台运行而不会停止我的应用程序?

我已经阅读了关于任务工厂和多线程的信息,但我没有得到线索。

pdf转换方法-


 public byte[] ConverToPdf(string source, string commandLocation)
        {

            string HtmlToPdfExePath = Server.MapPath("~/wkhtmltopdf.exe");
            Process p;
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = Path.Combine(commandLocation, HtmlToPdfExePath);
            psi.WorkingDirectory = Path.GetDirectoryName(psi.FileName);
            psi.UseShellExecute = false;
            psi.CreateNoWindow = true;
            psi.RedirectStandardInput = true;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardError = true;
            string args = "-q -n ";
            args += "--enable-javascript ";
            args += "--enable-plugins ";
            args += "--disable-smart-shrinking ";
            args += "--margin-bottom 20 ";
            args += "--margin-left 20 ";
            args += "--margin-right 20 ";
            args += "--margin-top 20 ";
            args += "--orientation Landscape ";
            args += "--outline-depth 0 ";
            args += "--page-size A4 ";
            args += "--encoding utf-8";
            args += " - -";
            psi.Arguments = args;
            p = Process.Start(psi);

            try
            {
                using (StreamWriter stdin = new StreamWriter(p.StandardInput.BaseStream, Encoding.UTF8))
                {
                    stdin.AutoFlush = true;
                    stdin.Write(source);
                }

                byte[] buffer = new byte[32768];
                byte[] file;
                using (var ms = new MemoryStream())
                {

                    while (true)
                    {
                        int read = p.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);
                        if (read <= 0)
                            break;
                        ms.Write(buffer, 0, read);
                    }
                    file = ms.ToArray();
                }
                p.StandardOutput.Close();
                p.WaitForExit(60000);
                int returnCode = p.ExitCode;
                p.Close();
                if (returnCode == 0)
                    return file;
                else
                    return file;
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("Could not create PDF", ex);
            }
            finally
            {
                p.Close();
                p.Dispose();
            }

            return null;
        }

更新- 我实际上是在尝试找到一种让后台工作人员完成其工作并从上述方法返回字节的方法。

我使用后台工作人员调用此方法的主要目的是返回调用结果的位置。

   public ActionResult DuesPDF()
        {
            var relativePath = "~/Views/Shared/_TestView.cshtml";
            string content;
            var view = ViewEngines.Engines.FindView(ControllerContext, relativePath, null);
            using (var writer = new StringWriter())
            {
                TempData["req"] = "DuesAndOverDuesChart";
                var context = new ViewContext(ControllerContext, view.View, ViewData, TempData, writer);
                view.View.Render(context, writer);
                writer.Flush();
                content = writer.ToString();
                byte[] pdfBuf = ConverToPdf(content, Server.MapPath("~/PDF/"));

                if (pdfBuf == null)
                    return null;
                return File(pdfBuf, "application/pdf");
            }
        }

这是我调用pdf方法的方法-ConverToPdf(content, Server.MapPath("~/PDF/"))

注意-

我要求通过上述ConverToPdf 方法与后台工作人员进行通信。

【问题讨论】:

    标签: c# pdf process backgroundworker wkhtmltopdf


    【解决方案1】:

    使用线程类它将在主线程以外的后台线程中运行您的方法。 此外,您在方法中返回 null,因此最好将返回类型设为 void 并且不返回 null。

    Thread threadObj = new Thread(new ThreadStart(()=>ConverToPdf("a","b")));
    threadObj.Start();
    

    更新:我假设您使用的是 Windows 窗体。根据您的更新,您可以轻松地看到您的主要方法需要响应才能进一步执行。现在为此,我建议您在后台线程中显示一些进度条,这样我就不会停止应用程序。当converttoPDF 方法完成时,它会停止进度条。在这种情况下,您的应用程序不会卡住,您将获得所需的响应。

    【讨论】:

    • 使它返回类型 void ,对我没有帮助。因为在那里它需要与调用它的方法进行通信。
    • 但是为什么又要和方法通信呢?让它变得简单,它认为你的逻辑有点混乱。如果您希望响应执行得比不在后台线程中运行该方法更进一步,或者如果您想在后台线程中运行意味着您的主线程不需要响应来进一步执行。我希望你明白我的意思。
    • 我的问题搞错了。让我更新一下以加深理解
    【解决方案2】:
    private void Button1_Click(object sender, EventArgs e)
            {
              bgworker.RunWorkerAsync();
            }
    private void bgworker_DoWork(object sender, DoWorkEventArgs e)
            {
              ConverToPdf(source, commandLocation);
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2015-01-18
      • 2018-11-29
      • 1970-01-01
      相关资源
      最近更新 更多