2016-07-14 9 views
0

Ich habe eine Klasse, die ein Objekt darstellt. Diese Klasse enthält einen Timer, der von Zeit zu Zeit eine Methode auslöst. Wenn jedoch schreibe ich etwas wie folgt aus:Richtig entworfen Klasse mit den Timern

var obj = new MyClass(); 

Dann am Ende wird das Objekt gelöscht und der Timer wird nicht einmal ein einziges Mal arbeiten. Aber ich brauche dieses Objekt im Speicher und ich brauche seine Arbeit nach dem Timer. So habe ich eine leere Methode einig nutzlosen Code enthält:

while(true){ 
int k=0; 
}  

Jetzt ist der Timer funktioniert, aber ich weiß nicht wirklich wie das Design. Irgendwelche Vorschläge, wie man es verbessert?

P.S. Dies ist, wie ich es testen: Ich habe eine Unit-Test erstellt, wo ich schrieb folgendes:

var obj = new MyClass(); 
int k=0; 

ich einen Haltepunkt in der zweiten Zeile haben. Und wenn ich es erreiche, warte ich, um sicherzustellen, dass Timer nie läuft. Um den Timer machen zu arbeiten, muss ich den Test ändern:

var obj = new MyClass(); 
obj.EmptyWork(); 
int k=0; 

Nun werden die Timer funktioniert, aber ich nie int k = 0 erreichen; und folglich kann ich das zweite Objekt usw. nicht erstellen.

+1

das Objekt, das Sie Leben schaffen, solange Sie eine Lebensdauer für sie haben, also wenn Sie einen Anruf Funktion und es erstellt das Objekt, aber es ist nur in diesem Objekt definiert, dann ist das, wie lange es lebt .. bis zum Ende der Funktion. Sie haben nicht genug gezeigt, um Ihre Lebensdauer des Objekts zu erklären oder was Sie wirklich tun – BugFinder

+0

Wenn der Ereignishandler Ihres Timers an eine Methode in Ihrer Klasse angehängt ist, wird sie am Leben erhalten, da Timer rooted sind, bis sie gelöscht werden. Veröffentlichen Sie den Code, in dem Sie den Timer instanziieren und anhängen, und wie Sie Ihre Klasse verwenden. – Groo

+0

Hinzugefügt mehr Beschreibung –

Antwort

0

Das Objekt wird gelöscht und es kann keine Arbeit mehr ausgeführt werden, da "am Ende" auf das Objekt nicht mehr zugegriffen werden kann. Wenn Sie das Objekt benötigen, müssen Sie darauf achten, dass es niemals unzugänglich wird. Wenn das Objekt in einer Funktion erstellt wird, muss es einer externen Variablen zugewiesen oder von der Funktion zurückgegeben werden.

+0

Wenn ich in der Testmethode bin: bar obj = new MyClass(); var k = 0; und mit einem Haltepunkt in der zweiten Zeile ist das Objekt immer noch zugänglich und noch am Leben. Aber der Timer hat nie ausgelöst. –

+0

Wenn der Timer im selben Thread ist und Sie die Ausführung durch den Breakpoint stoppen, ist dies ein korrektes Verhalten. – Kryszal

0

Wenn Sie einige Scheduler erstellen möchten, vielleicht die bessere Wahl ist nur zu schaffen, Aufgaben mit Quartz Bibliothek: http://www.quartz-scheduler.net

Sie die Methode isolieren/Klasse (Business-Logik) aus dem Scheduler (Timer) , die auf einfache Weise konfigurierbar sind.

Beispiel Ausführung des "HelloJob" von Dokumentation:

// define the job and tie it to our HelloJob class 
IJobDetail job = JobBuilder.Create<HelloJob>() 
    .WithIdentity("job1", "group1") 
    .Build(); 

// Trigger the job to run now, and then repeat every 10 seconds 
ITrigger trigger = TriggerBuilder.Create() 
    .WithIdentity("trigger1", "group1") 
    .StartNow() 
    .WithSimpleSchedule(x => x 
     .WithIntervalInSeconds(10) 
     .RepeatForever()) 
    .Build(); 

// Tell quartz to schedule the job using our trigger 
scheduler.ScheduleJob(job, trigger); 

Edited: können Sie Arbeitsobjekte erstellen, in dem ausgewählte Klassen der ijob implementieren (beispielsweise für Quarz-Bibliothek). Probe (nicht getestet):

interface IWork 
{ 
    void Run(object input); 
} 

class ImmediateWork : IWork 
{ 
    public void Run(object input) 
    { 
     // Code to run immediately (without schedule). 
    } 
} 

class ScheduledWork : IWork, IJob 
{ 
    public void Run(object input) 
    { 
     // Create the schedule for the 'Execute' method. 
     var job = JobBuilder.Create<ScheduledWork>().Build(); 
     var schedule = SimpleScheduleBuilder.RepeatHourlyForTotalCount(10); 
     var trigger = TriggerBuilder.Create().WithSchedule(schedule).StartNow().Build(); 
     ScheduleManager.Instance.ScheduleJob(job, trigger); 
    } 

    public void Execute(IJobExecutionContext context) 
    { 
     // Code to run after some time (with schedule). 
    } 
} 

// Simple singleton implementation of the global scheduler, for demonstration purposes only. 
static class ScheduleManager 
{ 
    private static IScheduler _instance; 
    public static IScheduler Instance => _instance ?? (_instance = createInstance()); 

    private static IScheduler createInstance() 
    { 
     // Create the instance of the scheduler. 
     var schedulerFactory = new StdSchedulerFactory(); 
     var scheduler = schedulerFactory.GetScheduler(); 

     // Start the scheduler. 
     if (!scheduler.IsStarted) 
      scheduler.Start(); 

     return scheduler; 
    } 
} 

Bei MVC Apps; wenn Sie wirklich den Timer in Ihrer Klasse benötigen, die eine lange Lebensdauer haben sollte, können Sie versuchen, verwenden Application State: https://msdn.microsoft.com/en-us/library/94xkskdf(v=vs.100).aspx

Verwandte Themen