Wenadin
Wenadin

Reputation: 396

Update graph continuously without freezing application

I'm working on a project that requires me to start a "test" for a variable amount of time and update a graph with data points in real time. I'm using a radzen chart to graph the data:

<RadzenStack class="rz-p-0 rz-p-md-6 rz-p-lg-12">
        <RadzenCard Variant="Variant.Outlined">

            <RadzenChart>
                <RadzenChartTooltipOptions Shared="@sharedTooltip" />
                <RadzenLineSeries Smooth="@smooth" Data="@testValveData" CategoryProperty="Time" Title="Test Valve1" LineType="LineType.Solid" ValueProperty="Pressure">

                </RadzenLineSeries>
                <RadzenCategoryAxis Padding="20" />
                <RadzenValueAxis>
                    <RadzenGridLines Visible="true" />
                    <RadzenAxisTitle Text="Pressure (PSI)" />
                </RadzenValueAxis>
            </RadzenChart>
        </RadzenCard>
        <RadzenCard>
            <RadzenStack Orientation="Orientation.Horizontal">
                <RadzenFormField Text="Duration" Style="width: 10%;">
                    <RadzenTextBox @bind-Value="@testDuration" />
                </RadzenFormField>
                <RadzenButton Text="Start test" ButtonStyle="ButtonStyle.Primary" Click="@(args => StartTest())" />
                <RadzenButton Text="End test" ButtonStyle="ButtonStyle.Primary" Click="@(args => StopTest())" />
            </RadzenStack>
        </RadzenCard>
</RadzenStack>

I have two buttons, the first runs the test, the second sets a boolean to stop the test. I also have a text box where the user can enter a time duration if they want to set a test duration instead of having to click the stop button. The issue I've been having is when I click the start test button, the application freezes. I suspect I'm doing something wrong with the tasks, but I'm not entirely sure where I'm going wrong. Here's my current code for the page:

@code {
bool sharedTooltip = true;
bool smooth = true;
bool stopTest = false;
string testDuration = string.Empty;
DataItem[]? testValveData;
string errorText = string.Empty;

class DataItem
{
    public required string Time { get; set; }
    public double Pressure { get; set; }
}
protected override async Task OnInitializedAsync()
{
    // Simulate asynchronous loading to demonstrate a loading indicator
    await Task.Delay(500);
    try
    {


        testValveData = new DataItem[]
        {
            new DataItem
            {
                Time = "1",
                Pressure = 12
            },
            new DataItem
            {
                Time = "2",
                Pressure = 20
            },
            new DataItem
            {
                Time = "3",
                Pressure = 30
            },
            new DataItem
            {
                Time = "4",
                Pressure = 40
            },
            new DataItem
            {
                Time = "5",
                Pressure = 35
            },
            new DataItem
            {
                Time = "6",
                Pressure = 25
            },
            new DataItem
            {
                Time = "7",
                Pressure = 18
            }
        };
    }
    catch (Exception ex)
    {
        errorText = ex.Message;
    }
}
private async void StartTest()
{

    stopTest = false;
    List<DataItem> tempList = new List<DataItem>();
    string[] formats = { @"m\m", @"h\h\ m\m", @"h\h\ m\m\ s\s", @"m\m\ s\s", @"s\s", @"h\h" };
    TimeSpan duration = TimeSpan.Zero;
    DateTime startTime = DateTime.UtcNow;
    if (!string.IsNullOrWhiteSpace(testDuration))
    {
        if (!TimeSpan.TryParseExact(testDuration, formats, null, out duration))
        {
            NotificationService.Notify(new NotificationMessage
                {
                    Severity = NotificationSeverity.Error,
                    Summary = "Invalid test duration format.",
                    Detail = $"Duration entered: {testDuration} is not valid. Valid formats are mm, hhmm, hhmmss, mmss, ss, hh"
                }); 
            return;
        }
    }
    var myTask = Task.Run(() => Run(duration, startTime));
    while (!myTask.IsCompleted)
    {
        await Task.Delay(200);
    }

}
private void Run(TimeSpan duration, DateTime startTime)
{
    Random rng = new Random();
    List<DataItem> returnList = new List<DataItem>();
    while (!stopTest || duration >= (DateTime.UtcNow - startTime))
    {
        returnList.Add(new DataItem
            {
                Time = (DateTime.UtcNow - startTime).ToString(),
                Pressure = rng.Next(1, 100)
            });
        testValveData = returnList.ToArray();
    }
}
private void StopTest()
{
    stopTest = true;
}

}

Upvotes: 0

Views: 57

Answers (0)

Related Questions