Tricky Problem Using Report Builder In Threads
Hello
I have a tricky problem which I need urgent help in fixing please. I am
using Report Builder 7.02, Delphi 6 and threads.
I have designed a report and saved it into a template. This report is
generated within seperate threads. Because of this, I have to do everything
dynamically. Initially, creating a report was not a problem, I just created
it using the main form of the application as the owner. I have now got a
problem because I want to incorporate a pipeline into the report. My
pipeline is very simple, just 1 field, I can add more later. Each thread
has its own pipeline. When I designed the report I used a report and
pipeline that were on my main form. Now I need to associate each new report
with its own pipeline. My pipeline on the main report is called
pipeMainReportData. My problem is that when I create a new pipeline, I
cannot call it pipeMainReportData if I create it with the main form as the
owner, because 2 pipelines are created with the same name by 2 different
threads, obviously I cannot have 2 components with the same name on the same
form.
I noticed that when you create a Report you have to give it a TComponent
object as the owner. So I tried creating a class
TThreadVar=CLASS(TComponent) a new instance of this class is created for
each thread.
When I create the report I specify a TThreadVar object as the owner. I then
specify the same object as the owner for the pipeline. When I then try to
access anything to do with the newly created report I get an access
violation.
Can anyone help? I dont want to have to go creating a seperate form for
every report, or go through the report finding all of the fields and
assigning them to the pipeline.
Cheers
Paul
I have a tricky problem which I need urgent help in fixing please. I am
using Report Builder 7.02, Delphi 6 and threads.
I have designed a report and saved it into a template. This report is
generated within seperate threads. Because of this, I have to do everything
dynamically. Initially, creating a report was not a problem, I just created
it using the main form of the application as the owner. I have now got a
problem because I want to incorporate a pipeline into the report. My
pipeline is very simple, just 1 field, I can add more later. Each thread
has its own pipeline. When I designed the report I used a report and
pipeline that were on my main form. Now I need to associate each new report
with its own pipeline. My pipeline on the main report is called
pipeMainReportData. My problem is that when I create a new pipeline, I
cannot call it pipeMainReportData if I create it with the main form as the
owner, because 2 pipelines are created with the same name by 2 different
threads, obviously I cannot have 2 components with the same name on the same
form.
I noticed that when you create a Report you have to give it a TComponent
object as the owner. So I tried creating a class
TThreadVar=CLASS(TComponent) a new instance of this class is created for
each thread.
When I create the report I specify a TThreadVar object as the owner. I then
specify the same object as the owner for the pipeline. When I then try to
access anything to do with the newly created report I get an access
violation.
Can anyone help? I dont want to have to go creating a seperate form for
every report, or go through the report finding all of the fields and
assigning them to the pipeline.
Cheers
Paul
This discussion has been closed.
Comments
The approach RB uses to implement threads for the Background Printing
feature and for the Report Server is to create a separate Form/DataModule
for each thread. The Form/DataModule acts as the Container for the report
and data access components. I recommend using a DataModule over a form -
Forms are designed to be used in threads, we have it working, but it is not
simple to implement.
You must make the DataModule component thread-safe - to do this see the
BackgrounPrintSettings topic in the RBuilder.hlp
--
Nard Moseley
Digital Metaphors
http://www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
I did look into BackgroundPrinting but I was worried about part of the text
you give in the help file,
"All objects and data access components the report relies on to execute must
reside on the form or data module where the report is located. In order to
determine if your report can be made to execute safely in a background
thread, make sure that the form does not rely on objects from other units in
the project. Any references to objects in other units of your project, which
are called from the container to support report generation, are not
supported when generating the report in a background thread."
Can you provide further clarification? I have a class in its own unit that
is responsible for filling the report. This seemed to me as though I could
not use it because the class is in another unit.
I provide data using the JIT Pipeline so do I still need to use a session
component?
I presume it is ok to use Background printing from within a new thread that
I have created?
Are there arny examples?
Cheers
Paul
For JITPipelines, you would want to use a separate JITPipeline instance for
each report. Therefore creating a DataModule that contains the JITPipeline
and Report will work fine. If the JITPipeline event-handler code is
accessing any shared resources, then you will need to manage that.
Background printing creates its own thread. This feature has not been
designed to be used in any other manner.
Perhaps the documentation is not clear. Object instances and shared
resources are what is important where thread safety is concerned. For
example, if each thread has its own Report instance that will not be
accessed by any code outside of the thread then the report is thread safe -
provide that the report class does contain code that accesses shared
resources - global singleton objects, global session objects, etc.
To simplify things, create separate instances of your custom objects that
exists inside the report container - the DataModule.
--
Nard Moseley
Digital Metaphors
http://www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com