TL/DR:
- I don't know if I'm using the asynchronous programming features of C# and Blazor correctly.
- Even though things technically work, I'd like some guidance if I'm doing things correctly.
- Also, I'm having issues trying to get my "loading spinner" to work. What am I doing wrong?
I'd like some guidance of my code is doing things the correct way.
I'm currently trying to use KubernetesClient with a Blazor webapp to interact with my kubernetes cluster.
As a test, I've tried to list nodes in a cluster, asynchronously. Things appear to work, but I'm unsure if I'm doing this correctly. Please see the code below:
@page "/kclient"
@using k8s
<PageTitle>Kubernetes Client Test</PageTitle>
<h1>Kubernetes Client Test</h1>
<br />
<button @onclick="@GetNodesAsync">Refresh Node List</button>
<br /><br />
<p>LOADING = @spin.ToString()</p>
<label>Node list:</label>
@if (spin)
{
<div ></div>
}else
{
<ul>
@if (MyNodes == null || MyNodes.Count == 0)
{
<li>No Nodes. Please try to refresh the node list.</li>
}else
{
@foreach(string node in MyNodes)
{
<li>@node</li>
}
}
</ul>
}
@code {
public bool spin = false;
public IKubernetes client { get; set; }
public List<string> MyNodes { get; set; }
protected override void OnInitialized()
{
spin = false;
KubernetesClientConfiguration config = KubernetesClientConfiguration.BuildConfigFromConfigFile("C:\\Users\\DevAdmin\\.kube\\config");
client = new Kubernetes(config);
System.Console.WriteLine("Base URI: " client.BaseUri);
}
async Task GetNodesAsync()
{
spin = true;
Task.Delay(1500).Wait();
await InvokeAsync(GetNodes);
spin = false;
await Task.CompletedTask;
}
public async void GetNodes()
{
MyNodes = null;
MyNodes = new List<string>();
System.Console.WriteLine("=== TRYING TO GET ALL NODES! ===");
var nodeList = await client.ListNodeAsync();
if (nodeList.Items.Count == 0)
{
Console.WriteLine("Empty! There are no nodes!");
}
else
{
foreach (var item in nodeList.Items)
{
//Console.WriteLine(item.Metadata.Name);
MyNodes.Add(item.Metadata.Name);
}
}
StateHasChanged();
}
}
The code above produces the page below:
When you click on the button "Refresh Node List" button, it will use the KubernetesClient library to get a list of Kubernetes nodes. Because I'm still new to .NET, Blazor, and asynchronous programming, I'm unsure if the way I'm retrieving the list of nodes and then showing it in a Blazor (razor?) page is correct.
Also I've been trying to show a loading spinner while waiting for the client to retrieve data, but I've been unable to get that working, and I'm sure it's because I'm not using async/tasks correctly.
Any guidance on my usage of the asynchronously programming features of C#/.NET or anything else with the code I've provided would be greatly appreciated.
Thanks in advance.
CodePudding user response:
I can spot a few issues. Always avoid async void
.
async Task GetNodesAsync()
{
spin = true;
//Task.Delay(1500).Wait(); -- .Wait() blocks the UI
await Task.Delay(1500);
//await InvokeAsync(GetNodes); -- this won't run on another Thread
await GetNodes();
spin = false;
//await Task.CompletedTask;
}
//public async void GetNodes()
public async Task GetNodes()
{
... // as before
//StateHasChanged(); -- not needed
}