TRichView Multiple Thread Problem
-
- Posts: 1
- Joined: Tue Apr 08, 2008 5:59 pm
TRichView Multiple Thread Problem
The company I work for recently purchased thesoftware. We are using it primarily as a tool to paint the processed data to a virtual canvas, and than using that data as a bitmap to send raw bitmap data to inkjet printers. We are developing using Builder 6.0 C++.
The application is used in a realtime production environment, were multiple documents might be printed at a given time. There are a variety of other events that occur while running, so each inkjet printer operates in it’s own thread. At Thread creation a TRichView Object is created for each thread, so there is no resource sharing between threads. The event that affects the TRichView is when the next document to print is sent to the thread. At this time we use a variety of CustomRichView controls (AddNL, AddPictureEx, Format, and a variety of changing fonts, line spacing, justification, etc). The end result is that the data is painted onto a canvas which is used to than be send on to the printer from another thread.
Were I am running into problems, is that as the number of printers on a production line grows, the number of TRichView objects grow. I have found that if one TRichView object is being used, we’ll say “Thread for Printer #1” is in the midst of assembling it’s data, and “Thread for Printer #2” begins to receive data, that once both of them begin accessing TRichView calls in their independent TRichView Objects, a thread will exception. As long as Thread #1 finishes first, thread #2 never has this problem.
Is there something I should be looking at?
The application is used in a realtime production environment, were multiple documents might be printed at a given time. There are a variety of other events that occur while running, so each inkjet printer operates in it’s own thread. At Thread creation a TRichView Object is created for each thread, so there is no resource sharing between threads. The event that affects the TRichView is when the next document to print is sent to the thread. At this time we use a variety of CustomRichView controls (AddNL, AddPictureEx, Format, and a variety of changing fonts, line spacing, justification, etc). The end result is that the data is painted onto a canvas which is used to than be send on to the printer from another thread.
Were I am running into problems, is that as the number of printers on a production line grows, the number of TRichView objects grow. I have found that if one TRichView object is being used, we’ll say “Thread for Printer #1” is in the midst of assembling it’s data, and “Thread for Printer #2” begins to receive data, that once both of them begin accessing TRichView calls in their independent TRichView Objects, a thread will exception. As long as Thread #1 finishes first, thread #2 never has this problem.
Is there something I should be looking at?
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Though TRichView code never change values of global variables or other shared resources, I am afraid that using them in threads must be very limited, because VCL library itself is not a thread safe.
I highly recommend to call all methods allocating and freeing memory or resources (that includes Add***, Format and many other TRichView methods), as well as all drawing methods in the context of the main process, using Synchronize method. And of course, several documents cannot be printed at the same time (because printing uses methods changing global state, such as Printer.BeginDoc/Page, etc.)
I highly recommend to call all methods allocating and freeing memory or resources (that includes Add***, Format and many other TRichView methods), as well as all drawing methods in the context of the main process, using Synchronize method. And of course, several documents cannot be printed at the same time (because printing uses methods changing global state, such as Printer.BeginDoc/Page, etc.)
-
- Posts: 75
- Joined: Fri Jan 06, 2012 8:13 pm
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
If preparing data for this table is time consuming, you can prepare them in threads.
But as for adding rows to the table, I am afraid no, you need to do it in the main process.
However, I believe that not adding rows, but reformatting takes 99% of time.
A large table can be generated very fast, if it is formatted once after preparing.
How do you insert these rows?
But as for adding rows to the table, I am afraid no, you need to do it in the main process.
However, I believe that not adding rows, but reformatting takes 99% of time.
A large table can be generated very fast, if it is formatted once after preparing.
How do you insert these rows?
-
- Posts: 75
- Joined: Fri Jan 06, 2012 8:13 pm
Table is global variable
Code: Select all
table := TRVTableItemInfo.CreateEx(NewMsgQry.RecordCount,1,rvchat.RVData);
table.BestWidth := 0;
table.ParaNo := -1;
table.Color := TColor($1FFFFFFF);//clNone ;
table.BorderVSpacing := 0;
table.BorderHSpacing := 1;
table.CellPadding := 0;
table.BorderWidth := 0;
table.CellBorderWidth := 0;
table.BorderStyle := rvtbColor;
table.CellBorderStyle := rvtbColor;
table.CellVSpacing:=5;
rvchat.AddItem('',table);
rvchat.Format;
-
- Posts: 75
- Joined: Fri Jan 06, 2012 8:13 pm
-
- Posts: 75
- Joined: Fri Jan 06, 2012 8:13 pm
-
- Posts: 75
- Joined: Fri Jan 06, 2012 8:13 pm
sample preparing cell's data:
Code: Select all
ParseString(RVtemp,author+'('+Qry.FieldByName('authorname').AsString+')',1);
RVtemp.AddBreakEx(2,rvbs3d,0);
sMSG:= Qry.FieldByName('msg').AsString;
mtype:= Qry.FieldByName('mtype').AsString;
if mtype='text' then begin
ParseString(RVtemp,sMSG,0);
end else if (mtype='image') or (mtype='video') then begin
imgstream:= ...
gr := RV_CreateGraphics(TGraphicClass(TJPEGImage));
gr.LoadFromStream(imgstream);
imgstream.Free;
FRVData.AddHotPictureTag(Qry.FieldByName('id').AsString,gr,0,rvvaBaseline,Qry.FieldByName('url').AsansiString);
prg:= TProgressBar.Create(nil);
prg.Width:=gr.Width;
FRVData.AddControlExTag('',prg,0,rvvaAbsBottom,Qry.FieldByName('id').AsString);
end;
-
- Posts: 75
- Joined: Fri Jan 06, 2012 8:13 pm
sample preparing cell's data:
Code: Select all
ParseString(RVtemp,author+'('+Qry.FieldByName('authorname').AsString+')',1);
RVtemp.AddBreakEx(2,rvbs3d,0);
sMSG:= Qry.FieldByName('msg').AsString;
mtype:= Qry.FieldByName('mtype').AsString;
if mtype='text' then begin
ParseString(RVtemp,sMSG,0);
end else if (mtype='image') or (mtype='video') then begin
imgstream:= ...
gr := RV_CreateGraphics(TGraphicClass(TJPEGImage));
gr.LoadFromStream(imgstream);
imgstream.Free;
RVtemp.AddHotPictureTag(Qry.FieldByName('id').AsString,gr,0,rvvaBaseline,Qry.FieldByName('url').AsansiString);
prg:= TProgressBar.Create(nil);
prg.Width:=gr.Width;
RVtemp.AddControlExTag('',prg,0,rvvaAbsBottom,Qry.FieldByName('id').AsString);
end;
...
RVtemp.SaveRvfToStream(MS);
MS.position:=0;
Table.Cells[ROW,0].Clear;
Table.Cells[ROW,0].InsertRVFFromStream(MS,0,cl,Background,Layout,True,nil);
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
May be you can prepare data directly in a table cell, without copying?
In your code, I see no formatting of RVTemp. Actually, for building a document and saving to RVF it is not needed. Without formatting, you can use an editor without a parent. Also, you can use TRVReportHelper.RichView, it does not need a parent (and must never be formatted by calling Format)
You end generation of the cell content by calling InsertRVFFromStream? Without formatting the main editor?
rvchat, is it TRichView or TRichViewEdit?
In your code, I see no formatting of RVTemp. Actually, for building a document and saving to RVF it is not needed. Without formatting, you can use an editor without a parent. Also, you can use TRVReportHelper.RichView, it does not need a parent (and must never be formatted by calling Format)
You end generation of the cell content by calling InsertRVFFromStream? Without formatting the main editor?
rvchat, is it TRichView or TRichViewEdit?
-
- Posts: 75
- Joined: Fri Jan 06, 2012 8:13 pm
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
-
- Posts: 75
- Joined: Fri Jan 06, 2012 8:13 pm
-
- Site Admin
- Posts: 17557
- Joined: Sat Aug 27, 2005 10:28 am
- Contact: