Bonjour,
Je suis en train de migrer une application de D2007 / UIB 2.1 / FB 2.1 vers DXE2 / UIB 2.5 / FB 2.5.1
Lors d'appel multiThread UIB je constate assez rapidement des exceptions suite aux appels UIB et dans la couche UIB elle même à divers endroits.
Pour m'affranchir des problèmes applicatifs liés à cette migration, j'ai testé le petit bout de code livré avec UIB (ThreadedQueries dans le dossier uib25\examples\UIB\Component\ThreadedQueries).
Je constate les mêmes problèmes que dans mon appli !
Idem avec FB 2.1
Idem avec base locale ou non.

Voici ce bout de code auquel j'ai ajouté quelques traces. rien de bien transcendant !

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
Unit main;

Interface

Uses
{$IFDEF LINUX}
  libc, QForms, QStdCtrls, QControls, QGraphics, QDialogs, QExtCtrls,
{$ELSE}
  Windows, Graphics, Controls, Forms, Messages, Dialogs, StdCtrls,
{$ENDIF}
  SysUtils, Classes, uib, SyncObjs, JvExStdCtrls, JvMemo, JvTimer;

Type
  TForm1 = Class(TForm)
    DataBase: TUIBDataBase;
    Button1: TButton;
    JvMemo1: TJvMemo;
    JvTimer1: TJvTimer;
    Procedure Button1Click(Sender: TObject);
    Procedure JvTimer1Timer(Sender: TObject);
  Private
    { Déclarations privées }
  Public
    { Déclarations publiques }
  End;

  TMyThread = Class(TThread)
  Protected
    Procedure Execute; Override;
    Destructor destroy; Override;
  End;

Var
  Form1: TForm1;
  Err  : String = '';

Implementation

{$R *.dfm}

Procedure TForm1.Button1Click(Sender: TObject);
Var
  i: integer;
Begin
  For i := 0 To 49 Do
    // For i := 0 To 3 Do
    TMyThread.Create(False);

End;

Var
  NuTh: integer = 0;

  { TMyThread }

Destructor TMyThread.destroy;
Begin
  Inherited;
End;

Procedure TMyThread.Execute;
Var
  Query         : TUIBQuery;
  Transaction   : TUIBTransaction;
  S1            : String;
  NuLect, MyNuTh: integer;
Begin
  FreeOnTerminate := True;
  inc(NuTh);
  MyNuTh := NuTh;
  // Form1.DataBase.Lock; //simulate single thread
  Try
    NuLect      := 0;
    Query       := TUIBQuery.Create(Nil);
    Transaction := TUIBTransaction.Create(Nil);
    Try
      Transaction.DataBase := Form1.DataBase;
      Query.Transaction    := Transaction;
      Query.FetchBlobs     := True;
      Query.SQL.Text       := 'select * from poste';
      Query.Open;
      While Not Query.EOF Do
      Begin
        inc(NuLect);
        S1 := Query.Fields.ByNameAsString['cod_poste'];
        Query.Next;
        sleep(10); // simulate activity
      End;

    Except
      On Erreur: Exception Do
      Begin
        Err := '** Thread=' + IntToStr(MyNuTh) + ' NuLect=' + IntToStr(NuLect) + ' // ' + Erreur.Message;
      End;
    End;

  Finally
    Query.Close(etmCommit);
    Query.Free;
    Transaction.Free;
    // Form1.DataBase.UnLock; //simulate single thread
  End;
End;

Procedure TForm1.JvTimer1Timer(Sender: TObject);
Begin
  If Err <> '' Then
  Begin
    JvMemo1.Lines.Add(Err);
    Err := '';
  End;
End;

End.
J'ai testé ce même code sur mon ancien environnement D2007 (en changeant juste les TUibxx par TJvUibxx) et tout fonctionne très bien.
Cela peut-il venir de la compatibilité UIB25 avec DXE2 ?
De mon installation des composants UIB 2.5 ? (j'ai juste modifié le uib.inc pour choisir la version FB)
Avez vous la possibilité de tester ce petit prog dans un environement DXE2/UIB25 (adaptez juste les parties rouges) ?
Merci de votre aide , je boucle la dessus depuis plusieurs jours !
jml.