Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
ERROR: AV's and IWButton.picture.data: the parameter is incorrect
#21
If you have variables showing between 2 different browsers, the only possible cases are:

1) You copied and pasted a URL including session ID and ALSO disabled browser security checks.

2) You are using globals or improperly sharing data within your own code.
Reply
#22
I have an IW app which is a map tile server that creates tiles (via bitmap then to png) if they do not already exist using threads.  UserSession thread should be equivalent in your case.

Below is a sample locking / unlocking a bitmap while editing and should eliminate collisions. 

Code:
try {
  try {

    ...
    if(!bmp->Canvas->TryLock()) { LogError("BMP TryLock failed."); return; }
    ...
    //SAMPLE BMP MANIPULATION
    ...
    bmp->Canvas->CopyMode = cmSrcCopy;
    bmp->Canvas->CopyRect(Types::TRect(0,0,IDIM,IDIM),bmp_odim->Canvas,Types::TRect((ODIM-IDIM)/2,(ODIM-IDIM)/2,((ODIM-IDIM)/2)+IDIM,((ODIM-IDIM)/2)+IDIM));
    //END SAMPLE
    ...

  } catch (Exception &e) {
    LogError("RenderToCanvas:  "+e.Message);
  }
} __finally {
  if(bmp->Canvas->LockCount) bmp->Canvas->Unlock();
}


Regards,
Mark
Reply
#23
Session ID is not in the url. SessionCookies and UseCookies are set to false. I see GAppID in html sources, that are different for the two browsers. As to the rest I have described it in detail, so do not know what I might have done incorrectly.

I need to know whether variables placed in the implementation section of the unit are independent for each session. Some of them I did not move yet to the user session unit and this may be the cause of the trouble. I suspect they may contain values from another session.
Reply
#24
(02-09-2020, 04:34 PM)MrSpock Wrote:
(02-09-2020, 03:34 PM)Joao Lira Wrote:
(02-09-2020, 03:02 PM)MrSpock Wrote: ...
I opened two sessions in two different-browser tabs and I got the same variable values for user1 and user2!! My photography app does not work for more than one user at the same time. Perhaps the problem is related to TIWImage put on the form at design time, and this component uses shared value for both the users. When I draw on TIWImage.picture.bitmap.canvas, the same value is shown for the other user.

MrSpock, 

Let me, please, understand better your test: have you opened two different web browsers (e.g., Chrome and Firefox), doing the test in both simultaneously, in which you realized that the variables had the same value, or did you open two tabs on the same web browser (e.g. Chrome or Firefox)?

Regards,
Joao Lira.
In two different web browsers.

There seems to have been a variable allowing having two separated sessions per IP, but from version to version it all changes and then does not work.

If you haven't declared the object of the class that encapsulates the variables of your test in the 'var' section of the 'unit' where you tested the variables (visible to other threads), but instead inside the form class itself, they should not have the same value because they could be overwritten by some previous assignments unless you had done it in your code. And this is not related only to IW, but to Delphi OOP as a whole, as you know. Could you share here the full source code of the test you did?

Regards,
Joao Lira.
Reply
#25
If you haven't declared the object of the class that encapsulates the variables of your test in the 'var' section of the 'unit' where you tested the variables (visible to other threads), but instead inside the form class itself, they should not have the same value because they could be overwritten by some previous assignments unless you had done it in your code. And this is not related only to IW, but to Delphi OOP as a whole, as you know. Could you share here the full source code of the test you did?

Regards,
Joao Lira.
==
Do you mean that I should move all variables (and maybe procedures too) from implementation var section to the form class public declaration and that is it? I shall try anyway, but it makes useless the idea of putting the variables in implementation in var section.
Reply
#26
So I have moved all variables from section
implementation=>var
to
form class=>public

and changed all procedures and functions to
form class=>public
in a very well known way

altogether it took less than half an hour.

Now two sessions in two browsers seem to work independently from each other. The problem is solved.
This was probably so obvious that it had not been mentioned in intraweb manual.
Reply
#27
Hi mrSpock,

I'm happy your problem is solved, and that it seemed so easy.

but I'm also a bit confused and unsure about it all. Could you please post a small example code, showing the difference between the two settings ?

I'm trying to figure out how this relates to the problems I have been experiencing.

My main problems is still the mix of ADOQuery call results among users, and I will try to put all ADO components in the UserSession unit and hope that is the solution for me.

Regards
Soren
Reply
#28
(02-09-2020, 10:28 AM)SorenJensen Wrote: Hi Dan,

That sounds plausible. I haven't done anything special to handle threading, in fact I have not even considered it. And to be honest, I'm a little unsure of how to go about making my code thread safe.

Could you (or other of course) point to any examples or post a simple code, showing the principles ?

Regards
Soren
Making your code thread safe is one issue, but I thought I read above that you are calling OTHER code (image handling code) that may not be thread safe.

For your own code, you can look at any of several blogs/articles about multi threading in Delphi.  Variables in your own objects (forms/usersession/etc) are going to be accessed only by one thread at a time unless you write some code that tries to access one session from another (you probably aren't trying to do that).  Your own code may not be the problem.

Trying to use other unsafe libraries are an entirely different issue.  As an example: If you are using a library that, maybe unknown to you, has some sort of global object or variable then you will have a problem when more than one session tries to access it at the same time.  You will need to determine if the libraries you are using are thread safe.

Dan
Reply
#29
Hi Dan,

Thanks for your reply. I'm not really handling any images, except I have been placing a BMP file at design time on a IWImage, later to find out a BMP file is not thread safe and that a PNG image would be better. After I changes all BMP to PNG, I have not had the picture.data error anymore. I'm not changing (or moving) any images during runtime.

My main issue is the multiuser problem. I'm using ADO components, accessing an SQL database, and when two users perform the same select at the same time (activates the same ADOQuery), as two different users on two different machines, both using Edge, user1 gets nothing and user2 gets the result of user1's select. Sometimes user1 gets user2's result but mostly get nothing. If there is just 1-2 seconds between the two users activates the call, everything is correct.

I have tried everything I can come up with (except making the ADOQuery calls thread safe): Servercontroller mode is MultiThread, ALL ADOuery components are defined in one datamodule being created by UserSession and all variables my forms use are defined in UserSession and all procedures and functions in my forms are defined in the public part of my Forms class definition.

I'll be doing some more tests today to try to establish exactly what and where is goes wrong, but I you have any proposals to what I can do, please feel free to tell me.

Regards
Soren
Reply
#30
(02-09-2020, 10:31 PM)SorenJensen Wrote: Hi mrSpock,

I'm happy your problem is solved, and that it seemed so easy.

but I'm also a bit confused and unsure about it all. Could you please post a small example code, showing the difference between the two settings ?

Regards
Soren
Certainly intraweb manual should have described in detail how to set multiuser independent database connection. So far I am not using a database but I will and may encounter the same problem.

As I did need to use the form code in other units, eventually I did not move the code to UserSession unit, so I made less disorder it the code. Moving the code to UserSession unit should be done only if there is no other way to share the code among units.

Before changes form class

Code:
TIWForm7 = class(TIWAppForm)
    stronaGłównaLink: TIWLink;
    IWImage1: TIWImage;
    IWFileUploader1: TIWFileUploader;
    akceptujButton: TIWButton;
    ktoryEtapLabel: TIWLabel;
    anulujButton: TIWButton;
    IWLabel1: TIWLabel;
    IWLabel4: TIWLabel;
    szerLabel: TIWLabel;
    procedure stronaGłównaLinkClick(Sender: TObject);
    procedure IWFileUploader1AsyncUploadCompleted(Sender: TObject; var DestPath,
      FileName: string; var SaveFile, Overwrite: Boolean);
    procedure IWAppFormCreate(Sender: TObject);
    procedure IWAppFormDestroy(Sender: TObject);
    procedure IWFileUploader1AsyncUploadError(Sender: TObject;
      EventParams: TStringList);
    procedure IWFileUploader1AsyncUploadSuccess(Sender: TObject;
      EventParams: TStringList);
    procedure IWImage1AsyncClick(Sender: TObject; EventParams: TStringList);
    procedure akceptujButtonClick(Sender: TObject);
    procedure anulujButtonClick(Sender: TObject);
  public
  end;

Before changes unit implementation part

Code:
implementation

var

    nazwaPlikuWysłanego, CurDir: string;
    s32,d32: Tbitmap32;
    m,d, bufor: Tbitmap;
    pic: Tpicture;
    momentWyboru: (wyświetl, przedPierwszymPunktem, przedDrugimPunktem);
    cropLTx, cropLTy, cropRBx, cropRBy: Integer;
    B: double;

Before changes unit implementation part functions and procedures header example

Code:
function X_od_Y(y: integer): integer;
begin
  result:= round((y-B)/A)
end;

after changes form class

Code:
TIWForm7 = class(TIWAppForm)
    stronaGłównaLink: TIWLink;
    IWImage1: TIWImage;
    IWFileUploader1: TIWFileUploader;
    akceptujButton: TIWButton;
    ktoryEtapLabel: TIWLabel;
    anulujButton: TIWButton;
    IWLabel1: TIWLabel;
    IWLabel4: TIWLabel;
    szerLabel: TIWLabel;
    procedure stronaGłównaLinkClick(Sender: TObject);
    procedure IWFileUploader1AsyncUploadCompleted(Sender: TObject; var DestPath,
      FileName: string; var SaveFile, Overwrite: Boolean);
    procedure IWAppFormCreate(Sender: TObject);
    procedure IWAppFormDestroy(Sender: TObject);
    procedure IWFileUploader1AsyncUploadError(Sender: TObject;
      EventParams: TStringList);
    procedure IWFileUploader1AsyncUploadSuccess(Sender: TObject;
      EventParams: TStringList);
    procedure IWImage1AsyncClick(Sender: TObject; EventParams: TStringList);
    procedure akceptujButtonClick(Sender: TObject);
    procedure anulujButtonClick(Sender: TObject);
  public
    nazwaPlikuWysłanego, CurDir: string;
    s32,d32: Tbitmap32;
    m,d, bufor: Tbitmap;
    pic: Tpicture;
    momentWyboru: (wyświetl, przedPierwszymPunktem, przedDrugimPunktem);
    cropLTx, cropLTy, cropRBx, cropRBy: Integer;
    B: double;
    function Y_od_X(x: integer): integer;
    function X_od_Y(y: integer): integer;
    function połączBitmapy(bmp1,bmp2: Tbitmap; procent: integer): TBitmap;
    function Randomstring(strLen: Integer): string;
    procedure transformacja(sourceBMP, destBMP: TBitmap32; SxTL,SyTL,SxBR,SyBR,
      Dx0,Dy0,Dx1,Dy1,Dx2,Dy2,Dx3,Dy3: Integer);
    procedure CropBitmap(InBitmap : TBitmap; XLT, YLT, szer, wys :Integer);
  end;

After changes unit implementation part does not contain any variables placed in var section. Certainly one should not use var section in the unit interface part either.

After changes a sample function header. "A" is a constant.

Code:
function TIWForm7.Y_od_X(x: integer): integer;
begin
  result:= round(A*x+B)
end;
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)