Avatar billede stringbuffer Nybegynder
24. januar 2001 - 17:30 Der er 9 kommentarer og
1 løsning

Periodisk process i ATL-komponent

I min ATL komponent (ASP-komponent) vil jeg gerne lave en proces, som f.eks. hver 10 sek tjekker tilstanden af nogle variabler.

Hvordan skal jeg kode det? Jeg søger et eksempel, som jeg kan rette til eget brug.

Jeg bruger VC 6.0
Avatar billede soepro Nybegynder
25. januar 2001 - 10:21 #1
Idet jeg tillader mig at formode, at en ATL komponent i princip virker som f.eks. en ActiveX component, skal du blot lægge en Timer komponent på din \"form\" og tilknytte det ønskede check til dens OnTimer event:

void __fastcall TfrmOCX::Time1OnTimer(TObject * Sender)
{
    // Check dine variabler og gør noget
    return;
}

Alternativt skal du starte en Thread som gør det samme, men så skal du enten lave Synchronize() med hovedtråden, eller til at indbygge noget signalling de to processer imellem. Min erfaring er at det nemmeste er at tilknytte en TCriticalSection til de variabler du vil checke:

// Globale variabler.
TCriticalSection varLock;

og så lave en Acquire/Release på den før/efter du checker variablerne i dit timer loop:

:
void __fastcall TfrmOCX::Time1OnTimer(TObject * Sender)
{
  varLock.Acquire();
  try
  {
    // Check dine variabler og gør noget
  }
  __finally
  {
    varLock.Release();
  };
}
:

og tilsvarende i dit hovedprogram, når de skal ændres:
:
void __fastcall TfrmMain::Button1OnCLick(TObject *Sender)
{
  varLock.Acquire();
  try
  {
    Variabel1 = 1-Variabel1; // Flip-Flop 0/1
    Variabel2 = Variabel1 ? \"ON\" : \"OFF\";
  }
  __finally
  {
    varLock.Release();
  };
}
:
Avatar billede soepro Nybegynder
25. januar 2001 - 10:40 #2
Du kan eventuelt bygge en ny klasse rundt on TCriticalSection, sådan at du kan indbygge Acquire/Release direkte i dine Setters og Getters vha. properties:

class protectedVariables
{
  protected:
  TCriticalSection lock;
  int Variable1;
  AnsiString Variable2;
  public:
  int GetVariable1(void) { return Variable1; };
  void SetVariable1(int value) { Variable1 = value; };
  AnsiString GetVariable2(void) { return Variable2; };
  void SetVariable2(AnsiString value) { Variable2 = value; };

  protectedVariables(void);
  protectedVariable2(int iValue, AnsiString sValue);
  __published:
  __property int* Variabel1 = (read=GetVariable1, write=SetVariable1, default=0);
  __property AnsiString* Variabel2 =(read=GetVariable2,write=SetVariable2, default=\"\");
}

hvor setters så kodes i stil med:

int protectedVariables::GetVariable1(void)
{
  int value = -1;
  lock.Acquire();
  try
  {
    value = Variable1;
  }
  __finally
  {
    lock.Release();
  };
  return value;
}

og setters tilsvarende. Hermed vil du bare kunne declarere dine \"globale\" variabler:

protectedVariables MineVars;

og spørge/ændre direkte på dem:

void __fastcall TfrmMain::Button1OnCLick(TObject *Sender)
{
  MineVars.Variabel1 = 1-Variabel1; // Flip-Flop 0/1
  MineVars.Variabel2 = Variabel1 ? \"ON\" : \"OFF\";
}
Avatar billede stringbuffer Nybegynder
25. januar 2001 - 12:10 #3
Der er ingen form, det er som sagt en server-komponent, den køre som et objekt med Application scope på IIS´eren
Avatar billede soepro Nybegynder
25. januar 2001 - 12:26 #4
I så fald er det vel signal metoden du skal anvende, og så skal du blot skabe dig en Thread som med det ønskede interval \"vågner til dåd\", dvs. en Execute structur i stil med:

void TmyThread::Execute(void)
{
  while (!Terminated)
  {
    // Check variabler & gør noget hvis nødvendigt.
    Sleep(10*1000); /* 10 * 1000ms = 10 sek. */
  }
}

Sleep vil under Windows suspende tråden i 10 sek. hvorefter Windows laver Resume på den, dvs. den anvender rent faktisk ikke CPU-tid i de 10 sek.
Avatar billede soepro Nybegynder
25. januar 2001 - 12:27 #5
Din server tråd og din \"tids\" tråd skal selvfølgelig være to objekter inden for samme application scope, ellers duer metoden ikke. (Så skal du til at lave rigtig messaging, hvor de to tråde sender beskeder til hinanden.)
Avatar billede stringbuffer Nybegynder
25. januar 2001 - 12:53 #6
Det tænkte jeg lidt på at gøre, men jeg bruger visual c++ og ikke c++ builder, så det med at lave en thread er ikke så ligetil som du viser her.

Jeg er som sagt interesseret i et eksempel på hvordan sådan noget kan gøres i et ATL-komponent, og jeg skrev at jeg bruger VC 6.0, ikke Bulder.

Desuden hvis jeg bare prøver at lave en funktion med sådan en løkke ville den aldrig returnere til den funktion, der satte den igang og dermed låse hele komponentet.
Avatar billede soepro Nybegynder
25. januar 2001 - 13:11 #7
Så er det bare den kaldende funktion der skal Sleep\'e.
Avatar billede stringbuffer Nybegynder
27. januar 2001 - 19:09 #8
Skal den kaldende funktion sleepe? jamen hvor? før den laver et kald til en funktion, der stadig skal køre en løkke med sleep?
hvad skal det hjælpe? Ingen af funktionerne returnerer, og man har stadig problem med et låst (læs: fucked up) funktionskald.

Der må være en måde at lave en thread på i ATL (i visual c++), som kan køre sådan en løkke, og jeg søger bare et eksempel. Hvis der IKKE findes nogen måde at gøre dette på vil jeg gerne se en begrundelse/dokumentation.

Sorry soepro, men jeg kan ikke bruge dit svar.
Avatar billede stringbuffer Nybegynder
29. januar 2001 - 04:56 #9
Jeg kan se at der er ingen, der har skrevet noget indlæg i dette spg. i flere dage, så jeg lukker det og opretter et mere specifikt spørgsmål.
Avatar billede soepro Nybegynder
30. januar 2001 - 10:39 #10
Det er nok en god ide - enten forstår jeg ikke dine spørgsmål, eller også forstår du ikke mine svar:

En tråd er en SEPARAT process den kører indtil nogen \"terminerer\" den, hvilket normal sker i den process der satte den igang.

En server component, er normal noget som via COM eller CORBA kald startes af styresystemet (Windows) og kører indtil enten en client-process terminerer den (hvis man tillader det) eller indtil styresystemet lukker COM-scop\'et. (Svarende til application scope.) Den normale procedure er at clienten laver et \"entry\" kald først, sådan at server-componenten ved at der er en ny client der (også) skal serviceres og så laver et \"exit\" kald når den er færdig. Server-komponenten kan så selv lukke sig ned, når antal klienter er nul.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester