This is a migrated thread and some comments may be shown as answers.

OMG...generating reports in parallel mixes data

6 Answers 206 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Michele
Top achievements
Rank 2
Michele asked on 28 Feb 2013, 08:01 AM
Hello,
I've revisited my report upgrading it to last stable build (so I've to use InstanceReport for passing data to the subreports) but I've got a really ugly problem.... I've got data mixed.... for example report for user 1 contins data for user2 and so on...I'm afraid that the static InstanceReport is the problem... that the report on thread x reads data from thread y and so on...

any feedback on this?
Thanks

6 Answers, 1 is accepted

Sort by
0
Tomas
Top achievements
Rank 1
answered on 28 Feb 2013, 10:52 AM
Hi,

Our customers have experienced the same. That is when two persons are simultaneously printing a report with subreports then the subreports data is mixed. Our program is built in Silverlight and we use PDF-print if that is relevant.

Threading issues could explain why this is happening and why I'm unable to recreate the problem. Would be great to hear what Telerik has to say about this.

Tomas
0
Svetoslav
Telerik team
answered on 28 Feb 2013, 12:14 PM
Hi,

Having no example that illustrates the incorrect behavior we can only guess what is happening. Anyway using shared (static) object from multiple threads looks like a good reason for such troubles. In general the Telerik.Reporting.Report object represents a report definition that at run time becomes the Telerik.Reporting.Processing.Report which is the actual object being data bound and rendered.

That said having a static (cached) instance of the report definition object won't save much memory/CPU and most probably the benefit from such approach doesn't justify the troubles caused. Moreover having a single report definition object used and most probably modified (through filters, parameters, etc) from two or more threads will reflect in a behavior similar to the one described below.

If this is the case I would suggest to avoid caching the report definition objects in static fields and create new instances for each processing operation/user.

In case you still experience any issues please send us a demo that illustrates the incorrect behavior so we can examine it on our end and get back to you with a proper solution.

All the best,
Svetoslav
the Telerik team

See what's new in Telerik Reporting Q1 2013. Register for the March 4 webinar to witness the impressive new visualizations in Telerik Reporting. Just for fun, 10 webinar attendees will be randomly selected to win a Telerik T-shirt and a $50 Gift Certificate to ThinkGeek. Register now! Seats are limited!

0
Michele
Top achievements
Rank 2
answered on 28 Feb 2013, 12:44 PM
Hello Svetoslav,
If I don't use static object I can't have them accessed via DataSource in the report designer... that's the reason I use static... you've just a ticket opened with id 648197 that shows how I binds data... (It's for another problem due to rendering slowness) but the data structure I use is the same... now I'm tring to create the DataObject outside and pass it to the report from the outside (before I was doing the creation of the object inside the NeedDataSource.... can you ensure that your IstanceReport is thread safe?

Before moving to this new approach (I mean '11 version) it was ok...
Thanks
0
Michele
Top achievements
Rank 2
answered on 28 Feb 2013, 01:35 PM
and btw I don't see any way of not using InstanceReport to specify the content of a subreport...
0
Tomas
Top achievements
Rank 1
answered on 01 Mar 2013, 08:02 AM

Hi Svetoslav,

I think I missunderstood what Paolo was doing and was more focused on the actual problem that is the data on the report gets mixed up.

My report is a ReportBook consisting of many InvoiceReports the InvoiceReport has a SubReport named InvoiceRows.
As DataSource the InvoiceReport uses an ObjectDataSource.
The subreport, InvoiceRows contains as the name suggests invocie rows. The SubReport gets it's data from the InvoiceReport through the following binding: DataSource = ReportItem.Parent.DataObject.InvoiceRows (By suggestion I got in support ticket 507347 - DataSource binding i SubReport).

However it looks like in some cases, which I'm unable to reproduce, but has happened to our customers several times is that data in the subreport (invoice rows) is actually coming from another invoice. From our logs I can see that when this has happened two persons almost simoultanesly have started printing a bunch of invoices.

Please let me know if you need more information

Tomas

0
Svetoslav
Telerik team
answered on 05 Mar 2013, 08:51 AM
Hello guys,

If you experience such problems - messed up data from different users/threads - the problem in most cases is a shared object; avoid using global objects to prevent such issues.

@Tomas:
If you manage to reproduce the issue please call us back and we will investigate it and give you a solution.

@Paolo:
I'm not sure what you mean with "ensure that your IstanceReport is thread safe"? From one side you use a static object in order to use it from all threads and avoid multiple instances and from the other side you want to modify it but the changed state to be maintained from per thread. I'm not sure that this is possible if the shared object is not read-only; instead it is your responsibility to manage the state of the shared object. Once again I would suggest to reconsider your approach and avoid using shared objects.

If you need to access the Telerik.Reporting.Report object from an expression/user function you can use the ReportItem global object; it returns the processing item in context.

For example suppose you have a TextBox item defined like this:

Telerik.Reporting.TextBox textBox1 = new Telerik.Reporting.TextBox();
textBox1.Value = "=Foo(ReportItem)";

Here is how to access the report definition (Telerik.Reporting.Report) object from withing the Foo user function:

public static string Foo(Telerik.Reporting.Processing.ReportItemBase item)
{
    Telerik.Reporting.Processing.TextBox processingTextBox = (item as Telerik.Reporting.Processing.TextBox);
     
    // to get the processing/runtime Report object:
    Telerik.Reporting.Processing.Report processingReport = processingTextBox.Report;
     
    // textBoxDefinition is actually the textBox1
    Telerik.Reporting.TextBox textBoxDefinition = (Telerik.Reporting.TextBox)processingTextBox.ItemDefinition;
     
    // get the report definition:
    Telerik.Reporting.Report reportDefinition = textBoxDefinition.Report;  
     
    // you can also get the report definition from the processing report object in the same way:
    Telerik.Reporting.Report reportDefinition1 = (Telerik.Reporting.Report)precessingReport.ItemDefinition;
   
    return "foo";
}

For more information please see Report Property and ItemDefinition Property.

All the best,
Svetoslav
the Telerik team

See what's new in Telerik Reporting Q1 2013. Register for the March 4 webinar to witness the impressive new visualizations in Telerik Reporting. Just for fun, 10 webinar attendees will be randomly selected to win a Telerik T-shirt and a $50 Gift Certificate to ThinkGeek. Register now! Seats are limited!

Tags
General Discussions
Asked by
Michele
Top achievements
Rank 2
Answers by
Tomas
Top achievements
Rank 1
Svetoslav
Telerik team
Michele
Top achievements
Rank 2
Share this question
or