Thursday, February 5, 2009

The maximum report processing jobs limit

ปัญหาของ Crystal report กับ ASP.NET The maximum report processing jobs limit
Server Error in '/site' Application.
The maximum report processing jobs limit configured by your system administrator has been reached.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Runtime.InteropServices.COMException: The maximum report processing jobs limit configured by your system administrator has been reached.
  • อันเนี๋ยปัญหาจาเกี่ยวกับ IIS+ASP.NET จำกัดจำนวนของ โพรเซสออกรายงานของ crystal reports
  • ประมาณนั้นคิดว่านะ แต่ก็ไม่ทราบสาเหตุจริงๆ หรอก เพราะ อ่อนภาษา ^^'
  • เห็นแต่เพื่อนเจอนะ พึ่งมาเจอกับตัวเองก็วันนี้ เลยเข้าใจแหละ ว่าปัญหามันน่าจะเกิดจากอาไร
  • ASP.NET เมื่อ clien เรียก crystal report viewer
  • iis จะทำสร้างไฟล์ .rpt ไว้ที่ c:/WINDOWS/Temp (Server 2003) ไว้เรื่อยๆ
  • ซึ่งถ้าเราไม่สั่ง close และ dispose ให้ object ของ report มันก็จะสร้าง rpt ขึ้นมาเรื่อยๆ ซึ่งพวกที่มีอยู่แล้วก็จะกลายเป็นไฟล์ขยะไป เสียพื้นที่ไปโดยใช่เหตุ
  • แต่เมื่อเราใส่ close และ dispose ต่อท้ายโค้ด ที่ตัว viewer เรียก report มันก็จะเรียกไม่ได้ เพราะ report object (ReportDocument) ถูก close และ dispose ไปแหละ (ถ้าเรียก close รายงานก็จะไม่มีอาไรแสดง แต่ถ้าเรียก dispose ออฟเจคก็จะเป็น null value)
  • สงสัยอย่างแล้ว app จะเป็นเหมือนเว็บมั้ยน้อ ^^'
  • app ก็เป็นเหมือนกันหว่า ถ้าเราใส่ close และ dispose ตามอ่ะ สงสัยตอนเขียน app ไม่เคย close และ dispose ตัว report เลยไม่เป็น ^^'
  • ที่ไม่ใส่เพราะว่า เห็นใน หน้า form.Designer.cs เห็นเข้าจัดการ dispose ให้ component คิดว่าน่าจะทำการทุก component นะใน form นั้นอ่ะ
  • กลับมาที่ asp.net ต่อ ถ้าเราใส่ close กับ dispose ที่ page_unload หรือ ที่ viewer_unload ถ้า client ปิดบราวเซอร์โดยตรง ทำให้ unload ทั้งสองเหตุการณ์ จะไม่ถูกเรียกขึ้นมา ซึ่ง close และ dispose ก็จะไม่สามารถทำงานได้


ReportDocument rpt = new ReportDocument();

rpt.Load(Server.MapPath(@"Order.rpt"));
rpt.Database.Tables[0].SetDataSource(ds.Tables[0]);
rpt.ParameterFields["Date"].CurrentValues.AddValue(date);

CrystalReportViewer1.ReportSource = rpt;
CrystalReportViewer1.DataBind();


  • ถ้าเราใช้ rpt.close() ต่อจากโค้ดด้านบนก็จะขึ้นประมาณนี้
Invalid report file path.
  • แต่ถ้าเราใช้ rpt.dispose() ต่อจากโค้ดด้านบนก็จะขึ้นประมาณ
Object reference not set to an instance of an object.
  • แต่ทำไมใน windows app ตัวออก report ใช้ close กับ dispose ต่อตัว viewer ได้มะเห็นมีปัญหาเลยอ่ะ
  • เพื่อนที่เคยเจอปัญหาเค้าว่า ก็ต้องเขียน จาวา สคริปสั่งสิ โฮจาขนาดนั้นเลยหรอเนี๋ย
  • อีกอย่างที่เค้าแก้ตอนนี้คือ เค้า export รายงานเป็น pdf แล้วให้ client ดูอีกที ซะงั้น
  • ซึ่งวิธีที่สองเนี๋ยก็เห็นในเว็บบอร์ดต่างประเทศ เค้าแนะนำกันนะ
  • มันก็เหมือนการบังคับให้ client ต้องลง pdf reader โดยปริยาย แต่ก็โอเคนะวิธีนี้ ถึงจะแก้อันนี้ได้ยังไง crystal report ก็ต้อง export to pdf ก่อนปริ้นอยู่ดี ซะงั้น แต่เค้าเปลี่ยนโหมดการปริ้นได้
  • และ เว็บบอร์ดต่างประเทศก็บอกวิธีแก้ประมาณนี้ด้วย

Sovled
  • เปิด regedit ขึ้นมาแล้วไปแก้ค่าตามพาธเนี๋ย
HKEY_LOCAL_MACHINE/SOftware/Crystal Decisions/Report Application Server/InprocServer/ReportDocument
  • Change the value of the field MaxNumOfRecords to -1(For Unlimited No. of records)
  • เครื่องเราค่าเริ่มต้นมันเป็น 3 หว่า คิดว่าค่านี้น่าจะหมายถึงตัว rpt ที่อยู่ใน Temp ว่ามากสุดได้เท่าไหร่
  • ถ้ามันเกินค่านั้นแล้วเมื่อเราทำการออกรายงานมันก็จะแสดงประมาณนี้นะิคิดว่า นะ อันนี้ก็ไม่รู้จริง
A processing limit was reached. Error in File C:\DOCUME~1\[HOST]\ASPNET\LOCALS~1\Temp\ReportBranch {0C5A35DA-2966-49C6-9952-392B9DFD3845}.rpt: Max processing time or Max records limit reached
  • หรือ อาจจะต้องแก้ตรงนี้ด้วย คือ แก้ให้มากกว่า 75 ว่างั้น
HKEY_LOCAL_MACHINE/SOftware/Crystal Decisions/Report Application Server/Server
  • เปลี่ยนค่าที่ PrintJobLimit โดยค่าเริ่มต้นจะเป็น 75 ให้เราแก้เป็น ค่าที่มากอ่ะ เห็นเพื่อนว่าถ้าค่ามากจะทำให้กินทรัพยากรของ Server เยอะซะงั้น อันนี้ก็ไม่ทราบข้อเท็จจริงนะ
  • ก็ประมาณนั้นแหละครับ
  • และวิธีแก้ปัญหาเรื่องการ close และ dispose เมื่อปิดบราวเซอร์ ต่างประเทศเค้าใช้ collection มาช่วยอ่ะนะ
  • โค้ดต้นฉบับจาก http://geekswithblogs.net/technetbytes/archive/2007/07/17/114008.aspx
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using CrystalDecisions;
using CrystalDecisions.CrystalReports;
using CrystalDecisions.CrystalReports.Engine;

namespace Test.Utilities
{
public class ReportFactory
{
protected static Queue reportQueue = new Queue();

protected static ReportClass CreateReport(Type reportClass)
{
object report = Activator.CreateInstance(reportClass);
reportQueue.Enqueue(report);
return (ReportClass)report;
}

public static ReportClass GetReport(Type reportClass)
{ //75 is my print job limit.
if (reportQueue.Count > 75) ((ReportClass)reportQueue.Dequeue()).Dispose();
return CreateReport(reportClass);
}
}
}


  • โค้ดด้านบนใช้ไงหว่ากำเราก็ยิ่งโง่ๆอยู่ด้วย งั้นดูโค้ดนี้ดีกว่า มีคนเอามาแก้ไขให้เราพอรู้เรื่องบ้างหน่อย
  • http://jaygpatel.blogspot.com/2008/02/maximum-job-processing-limit-error-in.html
  • อธิบายพร้อมดีจังแฮะ
  • # คิดว่าถ้าใช้โค้ดประมาณนี้คงไม่ต้องสั่ง close หรือ dispose ตอน unload หรอกมั้งคิดว่านะ
public class ReportFactory
{
protected static Queue reportQueue = new Queue();

public ReportFactory()
{ }

protected static ReportDocument CreateReport(ReportDocument reportClass)
{
//object report = Activator.CreateInstance(reportClass);
//Create new Instance of ReportDocument Object.
reportClass = new ReportDocument();
//Push ReportDocument object into Queue.
reportQueue.Enqueue(reportClass);
//Return ReportDocument Object
return (ReportDocument)reportClass;
}

public static ReportDocument GetReport(ReportDocument reportClass)
{
//Get No of object of ReportDocument in Queue.
string str = Convert.ToString(reportQueue.Count);
//If ReportDocument Object is more than Given Limit than delete the object from the queue.
if (reportQueue.Count > 5)
((ReportDocument)reportQueue.Dequeue()).Dispose();//Delete from the queue and dispose it.
return CreateReport(reportClass);
}
}


  • ไม่รู้ปัญหาจะอยู่ที่ Temp ปะนะ แต่ก็ทำได้แค่นี้อ่ะ พยายามหาแหละ ได้แค่นี้แหละ
  • สรุปสุดท้ายให้เลยคือ มั่วไปเรื่อย ^^'

Note
  • รันโดยใช้ aspnet temp จะอยู่ที่นี้ (XP) C:\Documents and Settings\<hostname>\ASPNET\Local Settings\Temp , C:\DOCUME~1\<hostname>\ASPNET\LOCALS~1\Temp
  • รันด้วย studio.net temp จะอยู่พาธเนี๋ย (XP) C:\Documents and Settings\<user>\Local Settings\Temp
  • Windows Server 2003 C:\WINDOWS\TEMP
  • ลองไปลองมาง่ายสุดไม่ต้องกังวลเรื่องอาไร export เป็น HTML ซะงั้นเลย ^^'
  • ExportFormatType.XXXXX

Refer

No comments:

Post a Comment