Gå til innhold

Anbefalte innlegg

Jeg har lagd en klasse for bruk i applikasjonen min, og i denne klassen vil det opprettes en tråd. Problemet er at når jeg da avslutter resten av programmet vil programmet fortsatt kjøre til denne tråden er avsluttet. Jeg tenkte først på å ha en constructor som avsluttet tråden (hvis den kjørte da) slik at tråden automatisk avsluttes hvis resten av programmet avsluttes, men problemet er at jeg ikke fatter hvordan man lager en destructor i C#. Jeg er egentlig C++ utvikler og er derfor vant til å bare bruke ~klassenavn().

 

Noen tanker om hvordan jeg kan løse dette?

Lenke til kommentar
Videoannonse
Annonse

Hei,

 

Du kan løse dette ved å sette "thread.IsBackground = true;". Tråden vil da avsluttes når applikasjonen din avsluttes.

 

Eks.

 

Thread thread = new Thread(new ThreadStart(test()));

thread.IsBackground = true;

thread.Start();

 

 

Håper dette hjelper.

 

 

Pål

Lenke til kommentar

Hei,

 

Du kan bruke thread.Abort() for å avslutte tråden. Du kan også lage et event som sender beskjed til løkken (jeg antar at du har en løkke i metoden som blir startet av tråden) om at nå må tråden avsluttes. Det er vanskelig å si hva du bør gjøre når jeg ikke vet mer om hva klassen gjør og hvordan du har bygd den opp.

 

Legger ved et eksempel på hvordan du kan bruke thread.Abort().

 

PS!

En destructor kalles slik ~klassenavn(){}

 

Eks.

 

using System;

using System.Threading;

 

namespace testThreads

{

class MainClass

{

 

[sTAThread]

static void Main(string[] args)

{

MainClass mainClass = new MainClass();

mainClass.Start();

}

 

//Destructor

~MainClass()

{

Console.WriteLine("Avslutter klasse.");

Thread.Sleep(2000);

}

 

private void Start()

{

Thread thread = new Thread(new ThreadStart(TestThread));

thread.Start();

Console.WriteLine("Tråd startet.");

Thread.Sleep(2000);

thread.Abort();

Console.WriteLine("Tråd avsluttes.");

//Thread.Sleep(2000);

thread.Join();

Console.WriteLine("Tråd avsluttet.");

Thread.Sleep(2000);

}

 

private void TestThread()

{

while(true)

{

Console.WriteLine("Tråd skriver.");

Thread.Sleep(1000);

}

}

}

}

 

Lykke til! :)

 

Pål

Lenke til kommentar

Nei, det er Visual Basic.NET

 

Constructoren trenger ikke nødvendigvis å være public.

 

Dispose har ingen ting med det å gjøre, Dispose kalles kun hvis objektet må frigjøre unmanaged minne.

Dette kan bli bruke i en using block, men da må det brukes et objekt som implementerer IDisposable

Lenke til kommentar

Jeg har lagd et lite eksempel på problemstillingen her:

 

http://home.online.no/~bj-bakke/threaddestructor.rar

 

Hvis man avslutter programmet uten å gjøre noe så går det fint, men hvis man trykker på knappen så lager den en lokal instans av klassen med tråden...denne tråden slutter ikke å gå da prosedyren til knappen er ferdig, slik den burde. Her ser du blant annet at jeg har prøvd å legge thread.abort() i destructoren. Ved å bytte ut thread.Abort() med en MessageBox.Show() og kjøre koden igjen vil heller aldri messageboxen bli vist. Det virker rett og slett på meg som om destructoren aldri blir kjørt selv om instansen skal/bør terminere sin eksistens da knappens event er over.

Lenke til kommentar

C++ != C#

En veldig viktig forskjell er minne-allokering - mens man i C++ må ha et veldig nært forhold til ctors og dtors, har C# søppeltømmere. (garbage collection)

Selv om C# i teorien har dtors, vet man aldri når de blir kalt - man har faktisk ingen garanti for at de noensinne blir kalt.

Dispose-patternet er en vanlig måte å løse dette på, eller eventhåndtering.

 

- grå -

Lenke til kommentar

Hei

 

kan du ikke bare lytte på en exit event i applikasjonene din og i fra denne kalle en shutdown funksjon som avslutter tråden?

 

pseudo kode

Aplliksjonen.cs

// konstruktør
Applikasjonen()
{
  this.OnExit += new EventHandler( this.Application_Exit ); // noe sånt husker ikke helt syntaksen
}

private void Application_Exit(object sender, EventArgs e)
{
   minKlasse.ShutDown();
}

MinKlasse.cs
bool bContinue = false;
Thread my_thread;

//konstruktør
MinKlasse()
{
  my_thread = new Thread( new ThreadStart(this.Start) );
}

public void Start()
{
  bContinue = true;
  my_thread.Start();
}


private void DoSomeWork()
{
try
{
  while(bContinue)
  {
       // Gjør arbeidet her

       Thread.Sleep(1000);
  }
}
catch(ThreadAbortException) {} // ignorer
}
}

public void ShutDown()
{
  bContinue = false;

  // venter 3 sec på a tråden skal avslutte
  if(my_thread.IsAlive)
      my_thread.Join(3000);

  // Hvis fremdeles aktiv - Tving tråden til å avslutte
  if(my_thread.IsAlive)
     my_thread.Abort(); 
}


 

koden er skrevet rett fra hukommelsen så forbehold om feil

men håper det hjelper deg i riktig retning

Endret av alftore
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...