<p>TL/DR:</p>
<ol>
<li>I don't know if I'm using the asynchronous programming features of
C# and Blazor correctly.</li>
<li>Even though things technically work, I'd like some guidance if I'm doing things correctly.</li>
<li>Also, I'm having issues trying to get my &quot;loading spinner&quot; to work. What am I doing wrong?</li>
</ol>
<p>I'd like some guidance of my code is doing things the correct way.</p>
<p>I'm currently trying to use KubernetesClient with a Blazor webapp to interact with my kubernetes cluster.</p>
<p>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:</p>
<pre><code>@page &quot;/kclient&quot;
@using k8s

&lt;PageTitle&gt;Kubernetes Client Test&lt;/PageTitle&gt;

&lt;h1&gt;Kubernetes Client Test&lt;/h1&gt;
&lt;br /&gt;
&lt;button class=&quot;btn btn-primary&quot; @onclick=&quot;@GetNodesAsync&quot;&gt;Refresh Node List&lt;/button&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;p&gt;LOADING = @spin.ToString()&lt;/p&gt;
&lt;label&gt;Node list:&lt;/label&gt;
@if (spin)
{
    &lt;div class=&quot;spinner&quot;&gt;&lt;/div&gt;
}else
{
    &lt;ul&gt;
        @if (MyNodes == null || MyNodes.Count == 0)
        {
            &lt;li&gt;No Nodes. Please try to refresh the node list.&lt;/li&gt;
        }else
        {
            @foreach(string node in MyNodes)
            {
                &lt;li&gt;@node&lt;/li&gt;
            }
        }

    &lt;/ul&gt;
}

@code {
    public bool spin = false;
    public IKubernetes client { get; set; }
    public List&lt;string&gt; MyNodes { get; set; }

    protected override void OnInitialized()
    {
        spin = false;
        KubernetesClientConfiguration config = KubernetesClientConfiguration.BuildConfigFromConfigFile(&quot;C:\\Users\\DevAdmin\\.kube\\config&quot;);
        client = new Kubernetes(config);
        System.Console.WriteLine(&quot;Base URI: &quot; + 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&lt;string&gt;();
        System.Console.WriteLine(&quot;=== TRYING TO GET ALL NODES! ===&quot;);
        var nodeList = await client.ListNodeAsync();
        if (nodeList.Items.Count == 0)
        {
            Console.WriteLine(&quot;Empty! There are no nodes!&quot;);
        }
        else
        {
            foreach (var item in nodeList.Items)
            {
                //Console.WriteLine(item.Metadata.Name);
                MyNodes.Add(item.Metadata.Name);
            }
        }
        StateHasChanged();
    }
}
</code></pre>
<p>The code above produces the page below:
<a href="https://i.stack.imgur.com/Tlmpv.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Tlmpv.png" alt="enter image description here" /></a></p>
<p>When you click on the button &quot;Refresh Node List&quot; 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.</p>
<p>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.</p>
<p>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.</p>
<p>Thanks in advance.</p>

<p>I can spot a few issues. Always avoid <code>async void</code>.</p>
<pre class="lang-cs prettyprint-override"><code>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
}
</code></pre>
