App cycle error on converting

Eduardo Gomez Romero 625 Reputation points
2024-10-01T00:07:01.5+00:00

I am binding app, for removal of Co2

For some reason the calculation is not very accurate,

The RemovedCo2Kilograms update every second. but the values are wrong

So, I wanted to start a timer, when I start the app

App Start

namespace METROWIND {
    public partial class App : Application {

        private readonly TurbinesService _turbinesService;

        public App(AppShell appShel, TurbinesService turbinesService) {
            Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(AppConstants.SYNCFUSION_KEY);

            InitializeComponent();

            MainPage = appShel;

            _turbinesService = turbinesService;
        }

        protected override void OnStart() {
            base.OnStart();

            var turbinePins = _turbinesService.GetTurbinePins(null); // Pass null for the commands

            // Start incrementing RemovedCo2Kilograms for each turbine
            _turbinesService.StartIncrementingRemovedCo2Kilograms(turbinePins);
        }

        protected override void OnSleep() {
            base.OnSleep();

            _turbinesService.StopIncrementing();
        }

        protected override void OnResume() {

            base.OnResume();

            // Optionally restart incrementing when the app resumes
            var turbinePins = _turbinesService.GetTurbinePins(null); // Pass null for the commands
            _turbinesService.StartIncrementingRemovedCo2Kilograms(turbinePins);
        }


    }
}

I have a Chaging stations page

public partial class ChargingStationsMapPageViewModel : ObservableObject {

    private readonly TurbinesService _turbinesService;

    private Microsoft.Maui.Controls.Maps.Map? MapView;

    public ObservableCollection<TurbinePin>? Turbines { get; set; }

    public ICommand? OnPinMarkerClickedCommand { get; }

    public double RemovedCo2Kilograms { get; set; }

    [ObservableProperty]
    bool isOptionsOpen;

    [ObservableProperty]
    bool isExpanded;

    public ChargingStationsMapPageViewModel(TurbinesService turbinesService) {

        OnPinMarkerClickedCommand = new Command<object>(OnPinMarkerClicked);

        _turbinesService = turbinesService;

        var SortedTurbinePins = _turbinesService.GetTurbinePins(OnPinMarkerClickedCommand)
            .OrderBy(t => t.Turbine!.InstalationDateTime);

        Turbines = new ObservableCollection<TurbinePin>(SortedTurbinePins);
    }

and a turbines collection page

public partial class TurbinesCollectionPageViewModel(TurbinesService turbinesService)
    : ChargingStationsMapPageViewModel(turbinesService) {

}

I want to bind the removedCo2Kilograms from my model here to the view, but I can't bemuse the values are wrong

User's image

Service

    public class TurbinesService(DeviceLanguageService deviceLanguageService) {
        private bool isRunning;
        private const double IncrementValue = 0.0007;
        private ObservableCollection<TurbinePin>? _turbinePins;
        public ObservableCollection<TurbinePin> GetTurbinePins(ICommand? pinClickedCommand) {
            _turbinePins = [
            new() {
                Turbine = new Turbine(deviceLanguageService) {
                    Id = 1,
                    Name = "Estación Ciudadela Simón Bolívar",
                    Label = "Charge station",
                    Address = "Av. de las Américas, Guayaquil 090513, Ecuador",
                    Location = new Location(-2.151993, -79.886109),
                    InstalationDateTime = new DateTime(2024, 8, 2),
                    Images = [
                        "charge_station.png",
                        "wind_turbine.png"
                    ],
                },
                PinClickedCommand = pinClickedCommand
            }];
            return _turbinePins;
        }
        public void StartIncrementingRemovedCo2Kilograms(ObservableCollection<TurbinePin> turbinePins) {
            _turbinePins = turbinePins;
            if (_turbinePins != null && !isRunning) {
                // Initialize RemovedCo2Kilograms with CalculatedRemovedCo2Kilograms
                foreach (var turbinePin in _turbinePins) {
                    turbinePin.Turbine!.RemovedCo2Kilograms = turbinePin.Turbine.CalculatedRemovedCo2Kilograms;
                }
                isRunning = true;
                IncrementRemovedCo2Kilograms();
            }
        }
        private async void IncrementRemovedCo2Kilograms() {
            while (isRunning) {
                await Task.Delay(1000);  // Increment every second
                foreach (var turbinePin in _turbinePins!) {
                    turbinePin.Turbine!.RemovedCo2Kilograms += IncrementValue;
                    Debug.WriteLine(turbinePin.Turbine!.RemovedCo2Kilograms);
                    turbinePin.Turbine.RemovedCo2Kilograms = RoundToDecimals(turbinePin.Turbine.RemovedCo2Kilograms, 3);
                }
            }
        }
        public static double RoundToDecimals(double value, int decimals = 2) {
            return Math.Round(value, decimals);
        }
        public void StopIncrementing() {
            isRunning = false;
        }
    }
}

Values fom the app

02:01:06:283	59.9497
02:01:07:285	59.950700000000005
02:01:08:293	738419.8416999999
02:01:09:278	738419.8426999999
02:01:10:280	738419.8437
02:01:11:289	738419.8447
02:01:12:279	738419.8457
02:01:13:284	738419.8467
02:01:14:282	738419.8476999999
02:01:15:291	738419.8487
02:01:16:280	738419.8497
02:01:17:283	738419.8507
02:01:18:288	738419.8517
02:01:19:282	738419.8526999999
02:01:20:280	738419.8537
02:01:21:278	738419.8547
02:01:22:290	738419.8557
02:01:23:291	738419.8567
02:01:24:279	738419.8576999999
02:01:25:538	738419.8587
02:01:26:529	738419.8597
02:01:27:534	738419.8607
02:01:28:536	738419.8617
02:01:29:541	738419.8626999999
02:01:30:533	738419.8637
02:01:31:542	738419.8646999999
02:01:32:533	738419.8416999999
02:01:33:531	738419.8416999999
02:01:34:531	738419.8426999999
02:01:35:530	738419.8437
02:01:36:532	738419.8447
02:01:37:534	738419.8457
02:01:38:536	738419.8467

Values I shoud get

User's image

and I do not know what is going on

and my model

    public partial class Turbine : ObservableObject {
        private readonly DeviceLanguageService _deviceLanguageService;
        public int Id { get; set; }
        public string? Name { get; set; }
        public string? Label { get; set; }
        public string? Address { get; set; }
        public Location? Location { get; set; }
        public DateTime InstalationDateTime { get; set; }
        public double TurbinePower { get; set; } = 0.37;
        public double TurbineCapacityFactor { get; set; } = 0.25;
        public double TutbineEmissionOffset { get; set; } = 0.45;
        public ObservableCollection<string>? Images { get; set; }
        [ObservableProperty]
        public double removedCo2Kilograms;
        #region Calulations
        public double EnergyPerDay => TurbinePower * TurbineCapacityFactor * 24;
        public double EnergyPerHour => EnergyPerDay / 24;
        public double EnergyPerSecond => EnergyPerHour / 60;
        public double RemovedCo2PerSecond => EnergyPerSecond * TutbineEmissionOffset;
        public int DaysPassedSinceInstallation => (DateTime.Today - InstalationDateTime).Days;
        public double EnergyProduced => EnergyPerDay * DaysPassedSinceInstallation;
        public double CalculatedRemovedCo2Kilograms => EnergyProduced * TutbineEmissionOffset;
        #endregion
        public string LocalizedInstalationDateTime {
            get {
                var currentCulture = new CultureInfo(_deviceLanguageService.GetDeviceLanguage());
                return InstalationDateTime.ToString("D", currentCulture);
            }
        }
        public Turbine(DeviceLanguageService deviceLanguageService) {
            _deviceLanguageService = deviceLanguageService;
            RemovedCo2Kilograms = CalculatedRemovedCo2Kilograms;
        }
    }
}


Also, when I resume the app, I need to continue where I left of

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,514 questions
{count} votes

Accepted answer
  1. Yonglun Liu (Shanghai Wicresoft Co,.Ltd.) 42,901 Reputation points Microsoft Vendor
    2024-10-04T05:57:27.65+00:00

    Hello,

    After testing, it was found that the problem that caused the large data gap was the setting of the scheduled task. Generally speaking, it is not recommended to put any code into an infinite loop, which will cause many problems, such as memory leaks and difficulty in synchronizing data between threads.

    For scheduled tasks, please use the officially recommended Timer to perform scheduling. This method is easy to use and thread-safe.

    You could refer to the following code:

    public class TurbinesService()
    {
        private bool isRunning;
        private const double IncrementValue = 0.0007;
        IDispatcherTimer Timer;
        private ObservableCollection<TurbinePin>? _turbinePins;
        public ObservableCollection<TurbinePin> GetTurbinePins(ICommand? pinClickedCommand)
        {
            _turbinePins = [
            new() {
                Turbine = new Turbine() {
                    Id = 1,
                    Name = "Estación Ciudadela Simón Bolívar",
                    Label = "Charge station",
                    Address = "Av. de las Américas, Guayaquil 090513, Ecuador",
                    Location = new Location(-2.151993, -79.886109),
                    InstalationDateTime = new DateTime(2024, 8, 2),
                },
            }];
            return _turbinePins;
        }
        public void StartIncrementingRemovedCo2Kilograms(ObservableCollection<TurbinePin> turbinePins)
        {
            _turbinePins = turbinePins;
            if (_turbinePins != null)
            {
                // Initialize RemovedCo2Kilograms with CalculatedRemovedCo2Kilograms
                foreach (var turbinePin in _turbinePins)
                {
                    turbinePin.Turbine!.RemovedCo2Kilograms = turbinePin.Turbine.CalculatedRemovedCo2Kilograms;                   
                }
                Timer = App.Current.Dispatcher.CreateTimer();
                Timer.Interval = TimeSpan.FromSeconds(1);
                Timer.Tick += (s, e) =>
                {
                    IncrementRemovedCo2Kilograms();
                };
                Timer.Start();
            }
        }
        private async void IncrementRemovedCo2Kilograms()
        {
            foreach (var turbinePin in _turbinePins!)
            {
                turbinePin.Turbine!.RemovedCo2Kilograms += IncrementValue;
                Debug.WriteLine(turbinePin.Turbine!.RemovedCo2Kilograms);
                turbinePin.Turbine.RemovedCo2Kilograms = RoundToDecimals(turbinePin.Turbine.RemovedCo2Kilograms, 3);
            }
        }
        public static double RoundToDecimals(double value, int decimals = 2)
        {
            return Math.Round(value, decimals);
        }
        public void StopIncrementing()
        {
            Timer.Stop();
        }
    }
    

    Best Regards,

    Alec Liu.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.