Home General
New Blog Posts: Merging Reports - Part 1 and Part 2

Tricky Problem Using Report Builder In Threads

edited October 2003 in General
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

Comments

  • edited October 2003

    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
  • edited October 2003
    Hi Nard

    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

  • edited October 2003

    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
This discussion has been closed.