J'ai créé une classe dérivée de Je veux que cette classe soit découplée du client. P> Ce type de fil a Le but d'exécuter une vérification simple (comme le nombre d'utilisateurs sont actuellement connectés à l'application, sans bloquer l'interface utilisateur), une idée simple est donc d'utiliser la méthode de synchronisation. P> De toute façon puisque je veux que ce soit découplé je passe dans le constructeur un paramètre de type p> où Quoi qu'il en soit, comment puis-je passer la valeur à TsyncMethod? Je devrais écrire le résultat sur une "place globale" puis à l'intérieur de mon Tsyncmethod je vérifie-moi? P> J'ai également essayé de penser à p> mais Bien sûr, lorsque j'appelle tthread code> qui s'exécute en arrière-plan une requête. tyncmethod code> est une méthode sur le client (un formulaire dans mon cas). P> synchroniser (mysyncmethod) code> je ne peux pas passer des paramètres à celui-ci. p> p>
5 Réponses :
Quelle version de DELPHI utilisez-vous? Si vous êtes sur D2009 ou plus récent, vous pouvez transmettre une méthode anonyme sur synchroniser code> qui ne prend aucun paramètre mais fait référence à des variables locales, les transmettant "sous le radar" dans le cadre de la fermeture. P>
Ok, je viens de rechercher des méthodes anonymes après votre réponse. Pourriez-vous s'il vous plaît expliquer que tu veux dire quoi? Si je passe une méthode anonyme Comment puis-je appeler la méthode de ma cliente TsyncMethod. Si j'appelle Synchroniser (la procédure commence quelque chose; fin) Comment utiliser TsyncMethod. S'il vous plaît comprendre que je suis nouveau aux méthodes anonymes. (J'utilise D2009).
Vous pouvez essayer mon composant TCommThread. Il vous permet de transmettre des données sur le fil principal sans vous soucier de l'une des complexités de threads ou de messages Windows.
Voici le code si vous souhaitez l'essayer. Vous pouvez également voir un exemple de code Ici . P>
bibliothèque de commTHead: p> Pour utiliser la bibliothèque, descendez simplement votre fil du TCOMMTHADAD Fil et remplacement de la procédure d'exécution: p> Suivant, créez un descendant du composant TstatusCommThreadDispatch et définissez ses événements. P> procedure THostDiscovery.DoOnReceiveThreadMessage(Sender: TObject;
MessageId: Integer; CommThreadParams: TCommThreadParams);
begin
inherited;
case MessageId of
CTID_MY_MESSAGE_ID:
begin
// Process the CTID_MY_MESSAGE_ID message
DoSomethingWithTheMessage(CommThreadParams.GetParam('MyThreadOutputParameter'),
CommThreadParams.GeObject('MyThreadObject'));
end;
end;
end;
en utilisant omnithreadlibrary : Création de l'objet de la tomnifuture démarre automatiquement l'arrière-plan Fil exécutant votre code. Plus tard, vous pouvez attendre sur le résultat en appelant .Value ou vous pouvez utiliser .Valuer ou .isdone à vérifier si le thread a déjà terminé ses travaux. P> P>
Bonne idée. Comme ma réponse, cela nécessitera également D2009 ou plus tard.
Merci, je garderai le lien dans mes favoris.
Pour un exemple aussi simple, vous pouvez placer la valeur souhaitée dans un champ de membre du fil (ou même dans la propriété de retour du fichier code> de la propriété code>), puis synchroniser () l'exécution du rappel en utilisant un Méthode de filetage intermédiaire, où vous pouvez ensuite transmettre la valeur au rappel. Par exemple:
Cela répond exactement à ma question: la méthode de thread intermédiaire était la liaison manquante. Quoi qu'il en soit, merci beaucoup à tous pour les réponses vraiment intéressantes, je les évite tous.
Créez un formulaire et ajoutez une liste de liste, deux boutons et modifiez votre formulaire. Ensuite, utilisez ce code:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TSyncMethod = procedure(ReturnValue: integer) of object;
TMyThread = class(TThread)
private
fLowerLimit: Integer;
fUpperLimit: Integer;
FMethod: TSyncMethod;
FMethodValue: Integer;
procedure UpdateMainThread;
protected
procedure Execute; override;
public
constructor Create(AMethod: TSyncMethod;lValue, uValue: Integer; Suspended: Boolean);
end;
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
ListBox1: TListBox;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
MyMethod: TSyncMethod;
ReturnValue : Integer;
CountingThread: TMyThread;
procedure MyTest(X : Integer);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
constructor TMyThread.Create(AMethod: TSyncMethod;lValue, uValue: Integer; Suspended: Boolean);
begin
FMethod := AMethod;
Inherited Create(Suspended);
fLowerLimit := lValue;
fUpperLimit := uValue;
FreeOnTerminate := True;
Priority := tpLowest;
end;
procedure TMyThread.Execute;
var
I: Integer;
begin
For I := fLowerLimit to fUpperLimit do
if (I mod 10) = 0 then
Synchronize(UpdateMainThread);
FMethod(FMethodValue);
end;
procedure TMyThread.UpdateMainThread;
begin
Form1.ListBox1.Items.Add('Hello World');
FMethodValue := Form1.ListBox1.Count;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
MyMethod := MyTest;
CountingThread := TMyThread.Create(MyMethod,22, 999, True);
CountingThread.Resume;
// ShowMessage(IntToStr(ReturnValue));
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage(Edit1.Text);
end;
procedure TForm1.MyTest(X: Integer);
begin
ShowMessage(IntToStr(X));
end;
end.