Permalänk

Timer C#

Tjena! Kan jag göra så att min Timer triggar en metod efter att min clock har kört en timme?

private static DateTime clock = DateTime.Now.Date.Add(new TimeSpan(7, 0, 0)); for(int i = 0; i < 100; i++) { var timer = new System.Threading.Timer( e => mm.ThreadLetHamstersPlay(), // Denna metoden vill jag null, TimeSpan.FromHours(clock.Hour), // ska starta efter en timme, alltså 10 varv TimeSpan.FromHours(clock.Hour) // sedan att den körs varje timme ); clock += TimeSpan.FromMinutes(6) }

Permalänk
Medlem

Kan du ge lite mer information, vad ska metoden som kallas göra? Måste du skriva det själv? Kan du tänka dig att använda externa bibliotek finns ju t.ex. Quartz.NET som är väldigt smidigt.

Permalänk
Skrivet av gonace:

Kan du ge lite mer information, vad ska metoden som kallas göra? Måste du skriva det själv? Kan du tänka dig att använda externa bibliotek finns ju t.ex. Quartz.NET som är väldigt smidigt.

Metoden ska bara kolla om några hamstrars utetid är null och sedan skicka ut dom i en timme och sedan kolla nästa gäng hamstrar en timme senare liksom, vill du se metoden så skickar jag den vidare bara, är en skoluppgift där jag ska simulera en dag på ett hamsterdagis Ska kolla in de paketet är inte säker på att vi får använda det dock!

Permalänk
Medlem

Vad är tanken med din kod egentligen? Det ser ut som att du blandar fiktiva timmar och "riktiga" timmar (som din Timer kommer gå efter, d.v.s systemklockan på din dator).

Enklast är att skippa dina Timers och fortsätta med din for-loop á 100 iterationer och din egna "clock".
Du vet att varje iteration är 6 minuter i fiktiv tid, d.v.s. 10 iterationer per timme. Hur ska du enklast kolla om det nu gått en timme från att du sist släppte ut hamstrarna? Jo du kollar vilken iteration du är på just nu.

Antingen skapar du ett heltal vars enda syfte är att hålla koll på tiden tills du når en timme (10 iterationer) och sedan nollställas igen, för att på så vis ticka upp till 1 timme om och om igen.
Det andra alternativet är att använda dig av Modulus-operatorn vars syfte är att ge dig rest-värdet på en division. Du kan alltså kolla om nuvarande index i din for-loop är jämnt delbar med 10 (modulus 10 == 0) och på så vis veta exakt i vilket varv du är på en timme.

for(int i = 0; i < 100; i++){ // Kollar om resten av i / 10 är 0 if(i != 0 && i % 10 == 0){ LetTheHamstersPlay(); } ... }

Visa signatur

NZXT H510 Flow MSI B450 Tomahawk MAX
AMD Ryzen 5800X3D RX 7900XTX Kingston Fury 64GB
LG C2 42" 4K@120Hz AOC Q27G2U 1440P@144Hz

Permalänk
Skrivet av PapaDiouf:

Tjena! Kan jag göra så att min Timer triggar en metod efter att min clock har kört en timme?

private static DateTime clock = DateTime.Now.Date.Add(new TimeSpan(7, 0, 0)); for(int i = 0; i < 100; i++) { var timer = new System.Threading.Timer( e => mm.ThreadLetHamstersPlay(), // Denna metoden vill jag null, TimeSpan.FromHours(clock.Hour), // ska starta efter en timme, alltså 10 varv TimeSpan.FromHours(clock.Hour) // sedan att den körs varje timme ); clock += TimeSpan.FromMinutes(6) }

Det finns många sätt att göra det du vill.
Visar på två sätt, antingen via en timer eller som de flesta nog rekommenderar en vanlig loop.
Det finns naturligtvis massor att justera i koden nedan, men bara för att ge dig några exempel.

namespace HamsterCare { using System; using System.Collections.Generic; using System.Timers; using Microsoft.EntityFrameworkCore; internal class Program { public delegate void ShowStatusDelegate(); public delegate void ShowStatusDelegateWithArguments(Status status); public static event ShowStatusDelegate ShowStatusEvent; public static event ShowStatusDelegateWithArguments ShowStatusEventWithArguments; public static void Main() { using var context = DatabaseHelper.NewContext(); ManageFacilityByTimerAndUsingActionCallback(); // or use this // ManageFacilityByLoopAndUsingDelegateCallback(); Console.ReadKey(true); } private static void ManageFacilityByTimerAndUsingActionCallback() { // using a timer to trigger a check if work is needed (uses simulated time) // also uses an action but can be replaced by a delegate var exact = DateTime.Now; var from = new DateTime(exact.Year, exact.Month, exact.Day, 8, 0, 0); var to = new DateTime(exact.Year, exact.Month, exact.Day, 15, 0, 0); var ticks = 0; var timer = new Timer(300); timer.Elapsed += (sender, args) => { var now = GetSimulatedDateTime(@from, ticks++); DoWorkWithAction(now, ShowStatus); // or use this // DoWorkWithActionAndArguments(now, ShowStatusWithArguments); // remember to stop the timer if after 15.00 if (now >= to) { timer.Stop(); } }; timer.Enabled = true; } private static void ManageFacilityByLoopAndUsingDelegateCallback() { // using a loop a check if work is needed // also uses a delegate but can be replaced by an action var exact = DateTime.Now; var now = new DateTime(exact.Year, exact.Month, exact.Day, 8, 0, 0); var to = new DateTime(exact.Year, exact.Month, exact.Day, 15, 0, 0); ShowStatusEvent += ShowStatus; // or use this //ShowStatusEventWithArguments += ShowStatusWithArguments; // loop through between 08.00 and 15.00 with 10 minutes steps for (; now < to; now = now.AddMinutes(10)) { DoWorkWithDelegate(now); } } private static void DoWorkWithDelegate(DateTime now) { using var context = DatabaseHelper.NewContext(); // perform all work needed // .. // important to do before printing out the status context.SaveChanges(); // use a delegate (either with or without an argument) Program.ShowStatusEvent?.Invoke(); Program.ShowStatusEventWithArguments?.Invoke(new Status()); } private static void ShowStatus() { using var context = DatabaseHelper.NewContext(); // get the current status from the database and print to the console // .. Console.WriteLine("Show status without arguments.."); } private static void ShowStatusWithArguments(Status status) { // use the argument without directly and not go through the database // .. Console.WriteLine("Show status with arguments.."); } private static void DoWorkWithAction(DateTime now, Action callback) { using var context = DatabaseHelper.NewContext(); // perform all work needed // .. // important to do before printing out the status context.SaveChanges(); // use the action callback to report current status callback(); } private static void DoWorkWithActionAndArguments(DateTime now, Action<Status> callback) { using var context = DatabaseHelper.NewContext(); // perform all work needed // .. // important to do before printing out the status context.SaveChanges(); // use the action callback to report current status var status = new Status { // ... }; callback(status); } private static DateTime GetSimulatedDateTime( DateTime from, int ticks) { // each tick is treated as 10 min return from.AddMinutes(ticks * 10); } } public class Status { public bool Whatever1 { get; set; } public List<Animal> Whatever2 { get; set; } = new List<Animal>(); } public class Facility { public int Id { get; set; } public ICollection<Animal> Animals { get; set; } = new List<Animal>(); } public class Animal { public int Id { get; set; } public Gender Gender { get; set; } public DateTimeOffset ArrivalTime { get; set; } public DateTimeOffset FeedingTime { get; set; } public int FacilityId { get; set; } public Facility Facility { get; set; } } public enum Gender { Male, Female } public class DaycareContext : DbContext { public DaycareContext(DbContextOptions<DaycareContext> options) : base(options) { // empty.. } public virtual DbSet<Facility> Facilities { get; set; } public virtual DbSet<Animal> Animals { get; set; } } internal class DatabaseHelper { public static DaycareContext NewContext() { const string host = "(LocalDB)\\MSSQLLocalDB"; const string database = "hamster_care"; var connectionString = $"Data Source={host};Initial Catalog={database};Integrated Security=True;"; var dbContextBuilder = new DbContextOptionsBuilder<DaycareContext>(); dbContextBuilder.UseSqlServer(connectionString); return new DaycareContext(dbContextBuilder.Options); } } }

Felaktig kod kommentar
Permalänk
Skrivet av zoomster2:

Det finns många sätt att göra det du vill.
Visar på två sätt, antingen via en timer eller som de flesta nog rekommenderar en vanlig loop.
Det finns naturligtvis massor att justera i koden nedan, men bara för att ge dig några exempel.

namespace HamsterCare { using System; using System.Collections.Generic; using System.Timers; using Microsoft.EntityFrameworkCore; internal class Program { public delegate void ShowStatusDelegate(); public delegate void ShowStatusDelegateWithArguments(Status status); public static event ShowStatusDelegate ShowStatusEvent; public static event ShowStatusDelegateWithArguments ShowStatusEventWithArguments; public static void Main() { using var context = DatabaseHelper.NewContext(); ManageFacilityByTimerAndUsingActionCallback(); // or use this // ManageFacilityByLoopAndUsingDelegateCallback(); Console.ReadKey(true); } private static void ManageFacilityByTimerAndUsingActionCallback() { // using a timer to trigger a check if work is needed (uses simulated time) // also uses an action but can be replaced by a delegate var exact = DateTime.Now; var from = new DateTime(exact.Year, exact.Month, exact.Day, 8, 0, 0); var to = new DateTime(exact.Year, exact.Month, exact.Day, 15, 0, 0); var ticks = 0; var timer = new Timer(300); timer.Elapsed += (sender, args) => { var now = GetSimulatedDateTime(@from, ticks++); DoWorkWithAction(now, ShowStatus); // or use this // DoWorkWithActionAndArguments(now, ShowStatusWithArguments); // remember to stop the timer if after 15.00 if (now >= to) { timer.Stop(); } }; timer.Enabled = true; } private static void ManageFacilityByLoopAndUsingDelegateCallback() { // using a loop a check if work is needed // also uses a delegate but can be replaced by an action var exact = DateTime.Now; var now = new DateTime(exact.Year, exact.Month, exact.Day, 8, 0, 0); var to = new DateTime(exact.Year, exact.Month, exact.Day, 15, 0, 0); ShowStatusEvent += ShowStatus; // or use this //ShowStatusEventWithArguments += ShowStatusWithArguments; // loop through between 08.00 and 15.00 with 10 minutes steps for (; now < to; now = now.AddMinutes(10)) { DoWorkWithDelegate(now); } } private static void DoWorkWithDelegate(DateTime now) { using var context = DatabaseHelper.NewContext(); // perform all work needed // .. // important to do before printing out the status context.SaveChanges(); // use a delegate (either with or without an argument) Program.ShowStatusEvent?.Invoke(); Program.ShowStatusEventWithArguments?.Invoke(new Status()); } private static void ShowStatus() { using var context = DatabaseHelper.NewContext(); // get the current status from the database and print to the console // .. Console.WriteLine("Show status without arguments.."); } private static void ShowStatusWithArguments(Status status) { // use the argument without directly and not go through the database // .. Console.WriteLine("Show status with arguments.."); } private static void DoWorkWithAction(DateTime now, Action callback) { using var context = DatabaseHelper.NewContext(); // perform all work needed // .. // important to do before printing out the status context.SaveChanges(); // use the action callback to report current status callback(); } private static void DoWorkWithActionAndArguments(DateTime now, Action<Status> callback) { using var context = DatabaseHelper.NewContext(); // perform all work needed // .. // important to do before printing out the status context.SaveChanges(); // use the action callback to report current status var status = new Status { // ... }; callback(status); } private static DateTime GetSimulatedDateTime( DateTime from, int ticks) { // each tick is treated as 10 min return from.AddMinutes(ticks * 10); } } public class Status { public bool Whatever1 { get; set; } public List<Animal> Whatever2 { get; set; } = new List<Animal>(); } public class Facility { public int Id { get; set; } public ICollection<Animal> Animals { get; set; } = new List<Animal>(); } public class Animal { public int Id { get; set; } public Gender Gender { get; set; } public DateTimeOffset ArrivalTime { get; set; } public DateTimeOffset FeedingTime { get; set; } public int FacilityId { get; set; } public Facility Facility { get; set; } } public enum Gender { Male, Female } public class DaycareContext : DbContext { public DaycareContext(DbContextOptions<DaycareContext> options) : base(options) { // empty.. } public virtual DbSet<Facility> Facilities { get; set; } public virtual DbSet<Animal> Animals { get; set; } } internal class DatabaseHelper { public static DaycareContext NewContext() { const string host = "(LocalDB)\\MSSQLLocalDB"; const string database = "hamster_care"; var connectionString = $"Data Source={host};Initial Catalog={database};Integrated Security=True;"; var dbContextBuilder = new DbContextOptionsBuilder<DaycareContext>(); dbContextBuilder.UseSqlServer(connectionString); return new DaycareContext(dbContextBuilder.Options); } } }

Jäkla hjälte du är, tack snälla för många bra tips! Fick man lära sig något nytt idag med. Hade gärna velat bli bättre på events o delegates, för att kalla på diverse metoder efter en viss tid, men har väldigt svårt att få ihop logiken, plus att min uppgift ska va inne om några dagar så vill inte slösa alldeles för mycket tid på det just nu, dock måste jag göra det efter. Så kommer nog gå på loopandet du gav bra exempel på, now < to osv! Men för att ändå ställa någon fråga:

"public ICollection<Animal> Animals { get; set; } = new List<Animal>();"
Jag har exempelvis en IColltection<Hamster> i min ExerciseArea klass, där jag ska släppa ut hamstrarna, vet dock inte ens om jag använder den, för när jag lägger till Hamstrar i ExerciseArea kör jag:

getMaleHamster[i].ExerciseAreaID = availableSpaceInExerciseArea[i].ExerciseAreaID;

Vad fyller den för funktion?

Angående events o delegates, jag har ett event som skriver ut information om hamstrarna efter min metod har körts:

class HamstersOutOnExerciseAreaEventArgs : EventArgs { public HamstersOutOnExerciseAreaEventArgs(int numberOfHamstersOutOnExerciseArea = 0, string name = null, string gender = null) { NumberOfHamstersOutOnExerciseArea = numberOfHamstersOutOnExerciseArea; Name = name; Gender = gender; ArrivalExerciseArea = Program.timeDiff; } public DateTime ArrivalExerciseArea { get; set; } public int NumberOfHamstersOutOnExerciseArea { get; set; } public string Name { get; set; } public string Gender { get; set; } }

Sedan Invokar jag eventet efter första kollen, jag har en klass PrintToConsole där jag har håller texten som ska skrivas ut. Om jag exempelvis vill köra min metod när min fiktiva tid slår en timme genom hela dagen, har du nån bra sida för att läsa på om det? Inte microsofts gärna för där har jag svårt att få till det xD Eller något enkelt exempel som jag kan jobba med?

Permalänk
Skrivet av PapaDiouf:

Jäkla hjälte du är, tack snälla för många bra tips! Fick man lära sig något nytt idag med. Hade gärna velat bli bättre på events o delegates, för att kalla på diverse metoder efter en viss tid, men har väldigt svårt att få ihop logiken, plus att min uppgift ska va inne om några dagar så vill inte slösa alldeles för mycket tid på det just nu, dock måste jag göra det efter. Så kommer nog gå på loopandet du gav bra exempel på, now < to osv! Men för att ändå ställa någon fråga:

"public ICollection<Animal> Animals { get; set; } = new List<Animal>();"
Jag har exempelvis en IColltection<Hamster> i min ExerciseArea klass, där jag ska släppa ut hamstrarna, vet dock inte ens om jag använder den, för när jag lägger till Hamstrar i ExerciseArea kör jag:

getMaleHamster[i].ExerciseAreaID = availableSpaceInExerciseArea[i].ExerciseAreaID;

Vad fyller den för funktion?

Angående events o delegates, jag har ett event som skriver ut information om hamstrarna efter min metod har körts:

class HamstersOutOnExerciseAreaEventArgs : EventArgs { public HamstersOutOnExerciseAreaEventArgs(int numberOfHamstersOutOnExerciseArea = 0, string name = null, string gender = null) { NumberOfHamstersOutOnExerciseArea = numberOfHamstersOutOnExerciseArea; Name = name; Gender = gender; ArrivalExerciseArea = Program.timeDiff; } public DateTime ArrivalExerciseArea { get; set; } public int NumberOfHamstersOutOnExerciseArea { get; set; } public string Name { get; set; } public string Gender { get; set; } }

Sedan Invokar jag eventet efter första kollen, jag har en klass PrintToConsole där jag har håller texten som ska skrivas ut. Om jag exempelvis vill köra min metod när min fiktiva tid slår en timme genom hela dagen, har du nån bra sida för att läsa på om det? Inte microsofts gärna för där har jag svårt att få till det xD Eller något enkelt exempel som jag kan jobba med?

Utan att att se hela koden men om du kommer att använda en loop:
Varför inte titta på tick räknaren och anropa metoden print om jämn timme.

Om du använder en timer och simulerad tid:
Kanske titta på tiden om den är jämn timme eller om du har sparat när det senaste 'jobbet' kördes i databasen, se om det har gått en timme sen senaste 'jobbet'.

Hur du anropar till print klass är helt beroende på hur den är definerad och vart den ligger. Men ett varför inte ett enkelt metod anrop eller via en delegat/action som jag visade i exemplet ovan.

[Edit]
Och angående

getMaleHamster[i].ExerciseAreaID = availableSpaceInExerciseArea[i].ExerciseAreaID;

Det ser ut som du tilldelar i vilket exercise område hamstern ska hamna i. Men lite svårt utan att se koden.

Permalänk
Skrivet av zoomster2:

Utan att att se hela koden men om du kommer att använda en loop:
Varför inte titta på tick räknaren och anropa metoden print om jämn timme.

Om du använder en timer och simulerad tid:
Kanske titta på tiden om den är jämn timme eller om du har sparat när det senaste 'jobbet' kördes i databasen, se om det har gått en timme sen senaste 'jobbet'.

Hur du anropar till print klass är helt beroende på hur den är definerad och vart den ligger. Men ett varför inte ett enkelt metod anrop eller via en delegat/action som jag visade i exemplet ovan.

[Edit]
Och angående

getMaleHamster[i].ExerciseAreaID = availableSpaceInExerciseArea[i].ExerciseAreaID;

Det ser ut som du tilldelar i vilket exercise område hamstern ska hamna i. Men lite svårt utan att se koden.

Höll på med mitt projekt och insåg att jag använder EF och inte EF Core som jag ska. Eftersom jag inte kommit särskilt långt tänkte jag att jag ska börja om och göra det ordentligt från start. Försöker att skapa databasen nu efter att ha satt upp mina klasser. Vad gör jag för fel?

public class HamsterDbContext : DbContext { public HamsterDbContext(DbContextOptions<HamsterDbContext> options) : base(options) { } public virtual DbSet<Cage> Cages { get; set; } public virtual DbSet<ExerciseArea> ExerciseArea { get; set; } } internal class DatabaseHelper { public static HamsterDbContext NewContext() { const string host = @(LocalDB)\MSSQLLocalDB; const string database = "HamsterDaycare"; var connectionString = $"Data Source={host};Initial Catalog={database};Integrated Security=True;"; var dbContextBuilder = new DbContextOptionsBuilder<HamsterDbContext>(); dbContextBuilder.UseSqlServer(connectionString); return new HamsterDbContext(dbContextBuilder.Options); } }

Får felmeddelande "Unable to create an object of type 'HamsterDbContext'. For the different patterns supported at design time",
Detta efter att jag kör add-migration CreateDatabase?

Permalänk

Skrev säkert fel någonstans eller om jag behövde kalla på metoden NewContext kanske? Det löste sig iallafall när jag skrev:

public virtual DbSet<Hamster> Hamsters { get; set; } public virtual DbSet<Cage> Cages { get; set; } public virtual DbSet<ExerciseArea> ExerciseArea { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseSqlServer(@Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=HamsterDaycare;Integrated Security=true);