2014-08-30 2 views
0

신청서에보고 목적으로 wkhtmltopdf을 사용하고 있습니다. 그러나 그것은 예상대로 훌륭하게 작동합니다.백그라운드에서 프로세스를 실행하는 방법은 무엇입니까? C#

문제 - 아래와 같은 방법으로 문자열 원본을 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; 
     } 

Update- 을 변환 -.

이 메서드를 백그라운드 작업자와 호출하는 주된 목적은 결과로 호출 된 곳으로 다시 통신하는 것입니다. 여기

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"); 
      } 
     } 

내가 백그라운드 작업자와 ConverToPdf 방법 위의 통신을 요청하고 ConverToPdf(content, Server.MapPath("~/PDF/"))

참고 - PDF 파일의 방법 -를 호출하고이 방법입니다.

답변

2

스레드 클래스를 사용하십시오. 메인 스레드 이외의 백그라운드 스레드에서 메소드를 실행할 것입니다. 이상 당신이 당신의 방법에 null을 반환하므로 반환 유형을 무효로 만들고 null을 반환하지 않는 것이 좋습니다.

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

업데이트 : 나는 당신이 창 양식을 사용하는 가정입니다. 귀하의 업데이트에 따라 주요 메소드가 응답을 더 많이 실행해야한다는 것을 쉽게 볼 수 있습니다. 지금은 이것을 위해 백그라운드 스레드에 진행 표시 줄을 표시하여 응용 프로그램을 중단하지 않을 것을 제안합니다. converttoPDF 메서드가 완료되면 프로세스가 진행률 막대를 중지합니다. 이 경우 응용 프로그램이 멈추지 않고 필요한만큼 응답을 받게됩니다.

+0

무효 반환 형식으로 설정하면 도움이되지 않습니다. 왜냐하면 호출 된 곳으로부터 메소드에 다시 통신해야하기 때문입니다. – user3163213

+0

하지만 다시이 메소드와 통신하고 싶습니까? 당신의 논리가 조금 지저분하다고 생각하면 간단하게 만드십시오.응답을 백그라운드 스레드에서 메소드를 실행하지 않는 것 이상으로 실행하려면 백그라운드 스레드에서 실행하고 싶다면 기본 스레드가 응답을 더 이상 실행할 필요가 없다는 것을 의미합니다. 너가 내 요점을 알았 으면 좋겠어. –

+0

내 질문에 착각했습니다. 더 많은 이해를 위해 업데이트하겠습니다. – user3163213

0
private void Button1_Click(object sender, EventArgs e) 
     { 
      bgworker.RunWorkerAsync(); 
     } 
private void bgworker_DoWork(object sender, DoWorkEventArgs e) 
     { 
      ConverToPdf(source, commandLocation); 
     } 
관련 문제