[英]How to run process in background? c#
我在應用程序中使用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
方法與后台工作人員進行通信。
使用線程類,它將在除主線程之外的后台線程中運行您的方法。 此外,您還需要在方法中返回null,因此最好使返回類型為void並且不返回null。
Thread threadObj = new Thread(new ThreadStart(()=>ConverToPdf("a","b")));
threadObj.Start();
更新:我假設您正在使用Windows窗體。 根據您的更新,您可以輕松地看到您的main方法需要響應才能進一步執行。 現在,為此,我建議您在后台線程中顯示一些進度條,以便我不會停止應用程序。 當converttoPDF
方法完成時,處理停止進度條。 在這種情況下,您的應用程序不會卡死,您將根據需要獲得響應。
private void Button1_Click(object sender, EventArgs e)
{
bgworker.RunWorkerAsync();
}
private void bgworker_DoWork(object sender, DoWorkEventArgs e)
{
ConverToPdf(source, commandLocation);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.