Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[C#] Stoppen van uitvoeren van code in een threading.timer *

Pagina: 1
Acties:

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Hoi,

Misschien is de titel niet helemaal duidelijk maar ik zal proberen uit te leggen wat ik probeer.
Ik heb een System.Threading.Timer die een stukje code uitvoert (zoals de documentatie zegt op een aparte threadpool thread).

Deze code loopt in een service en er worden meerdere van deze "tasks" gestart met hun eigen interval.

Deze tasks bestaan uit losse "plugins" die aan een bepaalde interface voldoen.
De Timer maakt een Task aan (De plugin) en callt de Run() method van deze task.

Nu kan het zijn dat een task te lang duurt. Nu wil ik dus de Run() onderbreken. Ik kom echter al snel uit op een thread.Abort() of een Timer.Dispose() maar dat is niet echt netjes begrijp ik.

Even wat code om het een en ander te verduidelijken

Creeren van een task:
C#:
1
2
3
4
5
6
7
8
9
10
Task task = new Task(settings);
          
TimerCallback timerDelegate = new TimerCallback(task.Run);
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
System.Threading.Timer timer = new System.Threading.Timer(timerDelegate, 
autoResetEvent, 
settings.Interval, settings.Interval);


 _scheduledTasks.Add(task.Settings.SiteName + task.Settings.TaskName, task);


Het Task object
C#:
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
private ITask _taskHandler;

public Task(TaskSettings settings)
{ 
           
  //laad task assembly
  Assembly ass = Assembly.LoadFrom(settings.AssemblyLocation);
  Type type = ass.GetType(settings.ClassName);
  _taskHandler = (ITask)Activator.CreateInstance(type);     
}

 public void Run(object state)
        {
            try
            {
                if (_taskHandler.Enabled)
                {
                 
                    if (!_taskHandler.Busy)
                    {
                         // run task in assembly
                        _taskHandler.Run();
                    }
                    else
                    {
                       //hij is te lang bezig
                       // stop het executen van _taskHandler.Run()... maar hoe?
                    }

                }
            }
            catch (Exception ex)
            {
               //log fatal
            }
        }


En een voorbeeld Task assembly met de run method die afgebroken dient te worden.
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 public void Run()
 {
    try
    {
       //de code die hier uitgevoerd word
       // zou gestopt moeten worden als de service vind dat het te lang duurt
    }
    catch(Exception ex)
    {
    }
    finally
    {
    }
 }


Is het mogelijk wat ik wil of moet ik toch iets met thread.abort gaan doen?

[ Voor 3% gewijzigd door 4of9 op 14-10-2008 15:02 ]

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • Amras
  • Registratie: Januari 2003
  • Laatst online: 01-10 12:59
Als de code in de Run methode een loop is, zou je een Stop methode op de Task kunnen toevoegen die de loop onderbreekt (met een boolean o.i.d). De thread van de Task zal dan gewoon 'normaal' eindigen.

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
De run in de task is geen loop. Je zou als stappen in de run methode kunnen zien als openen/sluiten/lezen van files. Database acties, verzenden van mail etc. etc. Tasks dus die lang kunnen duren.

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • sig69
  • Registratie: Mei 2002
  • Laatst online: 01:12
Dan zul je tussen die stappen moeten controleren of er een stop requested is, en dan returnen

Roomba E5 te koop


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Om het net te doen zul je dan inderdaad zelf logica moeten implementeren om de task te stoppen. Bij het lezen/schrijven van een File zou dat bijvoorbeeld kunnen door in een stop methode de Stream te closen, dan springen de read/write methodes er als het goed is uit met een exception.

Een Thread.Abort() zou je echt pas in het uiterste geval dat bijvoorbeel een Task in een deadlock hangt moeten gebruiken.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Ik zal eens kijken of ik daar iets mee kan!
Dank je voor de tips.

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Wat is er mis met Thread.Abort? Enige wat dat doet is een exception gooien in de target-thread. Een task die het daar niet mee eens is kan altijd die exception afvangen, en verder gaan.

-niks-


  • Haan
  • Registratie: Februari 2004
  • Laatst online: 21:57

Haan

dotnetter

MLM schreef op woensdag 15 oktober 2008 @ 13:53:
Wat is er mis met Thread.Abort? Enige wat dat doet is een exception gooien in de target-thread. Een task die het daar niet mee eens is kan altijd die exception afvangen, en verder gaan.
van MSDN: B)

Thead.Abort should be avoided.

There's many reasons not to use Thread.Abort and ThreadAbortException
On certain platforms (like x64 and IA64) the abort can occur before Monitor.Enter and a try block (even with lock/SyncLock), leaving the monitor orphaned.
The ThreadAbortException can occur in 3rd party code not written to handle thread abort.
The thread can be aborted while processing a finally block in .NET 1.x
Uses exceptions for normal control flow logic.
Asynchronous exception can interrupt modification of shard state or resources, leaving them corrupted.
For more detail see:
http://msmvps.com/blogs/p...rly-designed-program.aspx
http://www.bluebytesoftwa...ortsAndOrphanedLocks.aspx
http://blogs.msdn.com/eri...ties-of-c-il-codegen.aspx
Misschien dat het stukje eronder nog interessant is voor de TS:

Alternative programming to using Thread.Abort

See
"Overview of Synchronization Primitives"
http://msdn.microsoft.com/en-us/library/ms228964.aspx

and
"Managed Threading Best Practices" for more information on how to avoid using Abort
http://msdn.microsoft.com...txz50.aspx?wt.slv=ColumnA

[ Voor 15% gewijzigd door Haan op 15-10-2008 14:11 ]

Kater? Eerst water, de rest komt later


  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Okay, dat wist ik niet :) Ik keek in mijn MSDN documentatie (.NET 3.5) en daar stond geen waarschuwing oid bij, dus ik ging er van uit dat het "veilig" was. Het verbaast me dat .NET dan geen "safe" methode heeft om dit op te lossen, anders dan workarounds.

-niks-

Pagina: 1