Aracılığıyla paylaş


ASP.NET Core Razor bileşeni işleme

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.

Uyarı

ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.

Bu makale, ASP.NET Core Razor uygulamalarında bileşen işlemesini ve bir bileşenin işlenmesini manuel olarak tetiklemek için Blazor ne zaman çağrılması gerektiğini açıklamaktadır StateHasChanged.

ComponentBase için işleme kuralları

Bileşenler, bir üst bileşen tarafından bileşen hiyerarşisine ilk eklendiklerinde işlenmelidir. Bir bileşenin işlemesi gereken tek zaman budur. Bileşenler başka zamanlarda kendi mantıkları ve kuralları doğrultusunda işlenebilir.

Razor bileşenleri temel sınıftan ComponentBase devralır ve bu, aşağıdaki zamanlarda yeniden çalıştırmayı tetikleme mantığını içerir:

Aşağıdakilerden biri doğruysa, parametre güncellemeleri nedeniyle yeniden oluşturulmayı atlayan ComponentBase'den devralınan bileşenler:

  • Tüm parametreler bilinen türler kümesinden† veya önceki parametre kümesi ayarlandıktan sonra değişmemiş herhangi bir ilkel türdendir .

    † Framework Blazor , değişiklik algılama için bir dizi yerleşik kural ve açık parametre türü denetimleri kullanır. Bu kurallar ve türler herhangi bir zamanda değiştirilebilir. Daha fazla bilgi için ASP.NET Core başvuru kaynağındaki API'ye bakın.

    Not

    .NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürüm için bir etiket seçmek amacıyla Dalları veya etiketleri değiştir açılır listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

  • Bileşenin ShouldRender metodunu geçersiz kılma false döndürür (varsayılan ComponentBase uygulama her zaman true döndürür).

İşleme akışını denetleme

Çoğu durumda ComponentBase uygulamalar, bir olay gerçekleştikten sonra bileşenlerin doğru alt kümesinin tekrardan işlenmesiyle sonuçlanır. Geliştiricilerin genellikle çerçeveye hangi bileşenlerin yeniden ve ne zaman yeniden çalıştıracaklarını bildirmek için el ile mantık sağlaması gerekmez. Çerçeve kurallarının genel etkisi, bir olay alan bileşenin kendisini yeniden oluşturması ve bu da parametre değerleri değişmiş olabilecek alt bileşenlerin yeniden başlatılmasını yinelemeli olarak tetiklemektedir.

Çerçeve kurallarının performans etkileri ve bir uygulamanın bileşen hiyerarşisini işleme için iyileştirme hakkında daha fazla bilgi için bkz . ASP.NET Çekirdek Blazor işleme performansı en iyi yöntemleri.

Akış Renderleme

Akış işlemeyistatik sunucu tarafı işleme (statik SSR) veya ön işleme ile kullanarak, yanıt akışındaki içerik güncellemelerini akışa alın ve uzun süreli asenkron görevleri tamamen işleyen bileşenler için kullanıcı deneyimini geliştirin.

Örneğin, sayfa yüklendiğinde verileri işlemek için uzun süre çalışan bir veritabanı sorgusu veya web API çağrısı yapan bir bileşen düşünün. Normalde, sunucu tarafı bileşeni işlemenin bir parçası olarak yürütülen zaman uyumsuz görevlerin, işlenen yanıt gönderilmeden önce tamamlanması gerekir ve bu da sayfanın yüklenmesini geciktirebilir. Sayfayı işlemedeki önemli gecikmeler kullanıcı deneyimine zarar veriyor. Kullanıcı deneyimini geliştirmek için akış işleme başlangıçta zaman uyumsuz işlemler yürütülürken tüm sayfayı yer tutucu içerikle hızlı bir şekilde işler. İşlemler tamamlandıktan sonra, güncelleştirilmiş içerik aynı yanıt bağlantısında istemciye gönderilir ve DOM'a düzeltme eki eklenir.

Akış işleme, sunucunun verilen çıkışı arabelleğe almaktan kaçınmasını gerektirir. Veriler oluşturulurken yanıt verilerinin istemciye akması gerekir. Veri arabelleğe almayı zorunlu kılan sunucular için akış işleme işlemi düzgün bir şekilde azalır ve akış işleme olmadan sayfa yüklenir.

Statik sunucu tarafı işleme (statik SSR) veya önceden işleme yaparken içerik güncelleştirmelerinin akışını sağlamak için .NET 9 veya sonraki sürümlerde bileşene [StreamRendering] özniteliğini uygulayın (.NET 8'de [StreamRendering(true)] kullanın). Akışlı güncelleştirmeler sayfadaki içeriğin değişmesine neden olabileceğinden akış işleme açıkça etkinleştirilmelidir. Özniteliği olmayan bileşenler, üst bileşen özelliği kullanıyorsa akış işlemeyi otomatik olarak benimser. Bir alt bileşendeki özniteliğe false geçerek bu noktada ve daha alt bileşen alt ağacında fonksiyonu devre dışı bırakın. özniteliği, bir Razor sınıf kitaplığı tarafından sağlanan bileşenlere uygulandığında işlevseldir.

Aşağıdaki örnek, Weather oluşturulan bir uygulamadaki Blazor Web App bileşenine dayanmaktadır. Task.Delay çağrısı, hava durumu verilerinin zaman uyumsuz olarak alınmasını simüle eder. Bileşen başlangıçta zaman uyumsuz gecikmenin tamamlanmasını beklemeden yer tutucu içeriği ("Loading...") işler. Asenkron gecikme tamamlandığında ve hava durumu verileri içeriği oluşturulduğunda, içerik yanıta aktarılır ve hava durumu tahmin tablosuna eklenir.

Weather.razor:

@page "/weather"
@attribute [StreamRendering]

...

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        ...
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    ...

    private WeatherForecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
        await Task.Delay(500);

        ...

        forecasts = ...
    }
}

Kullanıcı arabirimi yenilemesini gizleme (ShouldRender)

ShouldRender bir bileşen her işlendiğinde çağrılır. Kullanıcı arabirimini yenilemeyi yönetmek için ShouldRender öğesini geçersiz kılın. Uygulama döndürürse true, kullanıcı arabirimi yenilenir.

Geçersiz kılınmış olsa bile ShouldRender, bileşen her zaman başlangıçta işlenir.

ControlRender.razor:

@page "/control-render"

<PageTitle>Control Render</PageTitle>

<h1>Control Render Example</h1>

<label>
    <input type="checkbox" @bind="shouldRender" />
    Should Render?
</label>

<p>Current count: @currentCount</p>

<p>
    <button @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;
    private bool shouldRender = true;

    protected override bool ShouldRender() => shouldRender;

    private void IncrementCount() => currentCount++;
}
@page "/control-render"

<PageTitle>Control Render</PageTitle>

<h1>Control Render Example</h1>

<label>
    <input type="checkbox" @bind="shouldRender" />
    Should Render?
</label>

<p>Current count: @currentCount</p>

<p>
    <button @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;
    private bool shouldRender = true;

    protected override bool ShouldRender() => shouldRender;

    private void IncrementCount() => currentCount++;
}
@page "/control-render"

<label>
    <input type="checkbox" @bind="shouldRender" />
    Should Render?
</label>

<p>Current count: @currentCount</p>

<p>
    <button @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;
    private bool shouldRender = true;

    protected override bool ShouldRender()
    {
        return shouldRender;
    }

    private void IncrementCount()
    {
        currentCount++;
    }
}
@page "/control-render"

<label>
    <input type="checkbox" @bind="shouldRender" />
    Should Render?
</label>

<p>Current count: @currentCount</p>

<p>
    <button @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;
    private bool shouldRender = true;

    protected override bool ShouldRender()
    {
        return shouldRender;
    }

    private void IncrementCount()
    {
        currentCount++;
    }
}
@page "/control-render"

<label>
    <input type="checkbox" @bind="shouldRender" />
    Should Render?
</label>

<p>Current count: @currentCount</p>

<p>
    <button @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;
    private bool shouldRender = true;

    protected override bool ShouldRender()
    {
        return shouldRender;
    }

    private void IncrementCount()
    {
        currentCount++;
    }
}
@page "/control-render"

<label>
    <input type="checkbox" @bind="shouldRender" />
    Should Render?
</label>

<p>Current count: @currentCount</p>

<p>
    <button @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;
    private bool shouldRender = true;

    protected override bool ShouldRender()
    {
        return shouldRender;
    }

    private void IncrementCount()
    {
        currentCount++;
    }
}

ile ilgili performans en iyi yöntemleri hakkında daha fazla bilgi için ShouldRenderbkz. ASP.NET Çekirdek Blazor işleme performansı en iyi yöntemleri.

StateHasChanged

StateHasChanged çağrısı, uygulamanın ana iş parçacığı boş olduğunda bir yeniden işlemenin gerçekleşmesi için kuyruğa alınır.

Bileşenler işlenmek üzere sıraya alınır ve zaten bekleyen bir yeniden işleme varsa yeniden sıraya alınmaz. Bir bileşen bir döngüde ard arda StateHasChanged beş kez çağrı yaparsa, bileşen yalnızca bir kez görünür. Bu davranış, ComponentBaseiçinde kodlanır ve ek bir rerender kuyruğa almadan önce bir rerender kuyruğa alınıp alınmadığını denetler.

Bir bileşen aynı döngü sırasında birden çok kez işlenebilir ve bu durum genellikle bir bileşenin birbiriyle etkileşim kuran alt öğeleri olduğunda oluşur:

  • Ebeveyn bileşen birkaç alt öğeyi oluşturur.
  • Çocuk bileşenler üst öğede bir güncelleştirme çizer ve tetiklemesine neden olur.
  • Ebeveyn bileşen yeni durumla tekrar oluşturulur.

Bu tasarım, gereksiz işleme riski olmadan gerektiğinde çağrılmasını sağlar StateHasChanged . Bu davranışı, IComponent'i doğrudan uygulayarak ve bileşenin ne zaman işlendiğini manüel olarak kontrol ederek tek tek bileşenlerde her zaman denetim altına alabilirsiniz.

Aşağıdaki sayacı artıran, IncrementCount yöntemini çağıran ve sayacı yeniden artıran yöntemi göz önünde bulundurun:

private void IncrementCount()
{
    currentCount++;
    StateHasChanged();
    currentCount++;
}

Hata ayıklayıcıda kodu adım adım izlerken, currentCount++ çağrıldıktan hemen sonra ilk StateHasChanged yürütmenin kullanıcı arabirimde sayımı güncellediğini düşünebilirsiniz. Ancak, bu yöntemin yürütülmesi için zaman uyumlu işlem gerçekleştiğinden kullanıcı arabirimi bu noktada güncelleştirilmiş bir sayı göstermez. Olay işleyicisi bitene kadar bileşeni işlemek için bir fırsat yoktur. Kullanıcı arabirimi, tek bir işlemede her iki yürütme için de currentCount++ artış görüntüler.

Satır aralarında bir şey beklerseniz, beklenen çağrı render motoruna işleme şansı verir. Bazı geliştiricilerin bileşenlerinde bir milisaniyelik gecikmeyle Delay çağrısı yaparak işlemenin gerçekleşmesine olanak tanımasına bu durum neden oldu, ancak bir uygulamayı rastgele yavaşlatarak işlemeyi sıraya almayı önermiyoruz.

En iyi yaklaşım, bileşeni kodu zaman uyumsuz olarak işlemesi için zorlayarak, yürütülen görevin devamını sağladıktan sonra ikinci bir işleme ile yeni bir grupta işleme geçmesini beklemektir. Bu işlem, geçerli grupta bir işleme ve ardından ayrı bir grupta bir işleme daha yapılmasını sağlar. Task.Yield

Aşağıdaki düzeltilmiş IncrementCount yöntemini göz önünde bulundurun, çünkü StateHasChanged tarafından sıraya alınan işleme, Task.Yield çağrısıyla görev verildiğinde gerçekleştirilir ve bu nedenle kullanıcı arabirimi iki kez güncellenir.

private async Task IncrementCount()
{
    currentCount++;
    StateHasChanged();
    await Task.Yield();
    currentCount++;
}

Gereksiz işleme maliyetlerine neden olan yaygın bir hata olan StateHasChanged'i gereksiz yere çağırmamaya dikkat edin. Kodun şu durumlarda çağrılması StateHasChanged gerekmez:

  • Olayları rutin bir şekilde, zaman uyumlu veya zaman uyumsuz olarak işlemek, çoğu rutin olay işleyicisi için bir işleme ComponentBase tetikler.
  • Tipik yaşam döngüsü mantığı, OnInitialized veya OnParametersSetAsync gibi unsurlar, zaman uyumlu ya da zaman uyumsuz olarak uygulandığında, ComponentBase tipik yaşam döngüsü olayları için bir işleme tetikler.

Ancak, bu makalenin aşağıdaki bölümlerinde açıklanan durumlarda çağrı StateHasChanged yapmak mantıklı olabilir:

Eşzamansız bir işlemci, birden fazla eşzamansız aşamayı içerir.

Görevlerin .NET'te tanımlanma biçimi nedeniyle, bir alıcısı Task ara zaman uyumsuz durumları değil, yalnızca son tamamlanma durumunu gözlemleyebilir. Bu nedenle, ComponentBase yalnızca Task ilk kez döndürüldüğünde ve Task nihayet tamamlandığında yeniden çizimi tetikleyebilir. Çerçeve, bir bileşenin bir ara nokta serisindeki verileri döndürmesi gibi IAsyncEnumerable<T>diğer ara Tasknoktalarda bileşeni yeniden oluşturmayı bilemez. Ara noktalarda yeniden işlemek istiyorsanız, o noktalarda StateHasChanged çağırın.

Aşağıdaki CounterState1 bileşeni, IncrementCount yöntemi her yürütüldüğünde sayıyı dört kez güncelleştirir.

  • Otomatik işlemeler, currentCount ilk ve son artımlarından sonra gerçekleşir.
  • Çerçeve, StateHasChanged artırıldığı ara işleme noktalarında otomatik olarak yeniden render işlemini tetiklemediğinde, elle başlatılan render işlemleri currentCount çağrılarıyla tetiklenir.

CounterState1.razor:

@page "/counter-state-1"

<PageTitle>Counter State 1</PageTitle>

<h1>Counter State Example 1</h1>

<p>
    Current count: @currentCount
</p>

<p>
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;

    private async Task IncrementCount()
    {
        currentCount++;
        // Renders here automatically

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        // Renders here automatically
    }
}
@page "/counter-state-1"

<PageTitle>Counter State 1</PageTitle>

<h1>Counter State Example 1</h1>

<p>
    Current count: @currentCount
</p>

<p>
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;

    private async Task IncrementCount()
    {
        currentCount++;
        // Renders here automatically

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        // Renders here automatically
    }
}
@page "/counter-state-1"

<p>
    Current count: @currentCount
</p>

<p>
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;

    private async Task IncrementCount()
    {
        currentCount++;
        // Renders here automatically

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        // Renders here automatically
    }
}
@page "/counter-state-1"

<p>
    Current count: @currentCount
</p>

<p>
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;

    private async Task IncrementCount()
    {
        currentCount++;
        // Renders here automatically

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        // Renders here automatically
    }
}
@page "/counter-state-1"

<p>
    Current count: @currentCount
</p>

<p>
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;

    private async Task IncrementCount()
    {
        currentCount++;
        // Renders here automatically

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        // Renders here automatically
    }
}
@page "/counter-state-1"

<p>
    Current count: @currentCount
</p>

<p>
    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</p>

@code {
    private int currentCount = 0;

    private async Task IncrementCount()
    {
        currentCount++;
        // Renders here automatically

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        StateHasChanged();

        await Task.Delay(1000);
        currentCount++;
        // Renders here automatically
    }
}

İşleme ve olay işleme sistemine Blazor harici bir öğeden çağrı alma

ComponentBase yalnızca kendi yaşam döngüsü yöntemlerini ve Blazortetiklenen olayları bilir. ComponentBase kodda gerçekleşebilecek diğer olayları bilmez. Örneğin, özel bir veri deposu tarafından tetiklenen C# olayları Blazor için bilinmemektedir. Bu tür olayların kullanıcı arabiriminde güncellenmiş değerleri görüntülemek için yeniden çizim işlemini tetiklemesi amacıyla, StateHasChanged öğesini çağırın.

Aşağıdaki CounterState2 bileşenini göz önünde bulundurun; bu bileşen, sayıyı düzenli aralıklarla güncelleştirmek için System.Timers.Timer kullanır ve kullanıcı arabirimini güncellemek için StateHasChanged çağırır.

  • OnTimerCallback herhangi bir Blazoryönetilen işleme akışının veya olay bildiriminin dışında çalışır. Bu nedenle, OnTimerCallback, geri çağırma sırasında StateHasChanged üzerindeki değişikliklerin Blazor tarafından fark edilmemesi nedeniyle currentCount çağırmalıdır.
  • Bileşen, IDisposable uygular; burada, çerçeve Timer yöntemini çağırdığında Dispose bertaraf edilir. Daha fazla bilgi için bkz. ASP.NET Core Razor bileşen imhası.

Geri çağırma, Blazor eşitleme bağlamı dışında çağrıldığından, bileşen, OnTimerCallback mantığını ComponentBase.InvokeAsync içinde sarmalaması ve işleyicinin eşitleme bağlamına taşımak gerekir. Bu, diğer UI çerçevelerinde UI iş parçacığına yönlendirmeye eşdeğerdir. StateHasChanged yalnızca işleyicinin eşitleme bağlamından çağrılabilir ve aksi takdirde bir özel durum oluşturur:

System.InvalidOperationException: 'Geçerli iş parçacığı, Dispatcher ile bağlantılı değil. İşleme veya bileşen durumunu tetiklerken yürütmeyi Dispatcher'a geçmek için InvokeAsync() kullanın.'

CounterState2.razor:

@page "/counter-state-2"
@using System.Timers
@implements IDisposable

<PageTitle>Counter State 2</PageTitle>

<h1>Counter State Example 2</h1>

<p>
    This counter demonstrates <code>Timer</code> disposal.
</p>

<p>
    Current count: @currentCount
</p>

@code {
    private int currentCount = 0;
    private Timer timer = new(1000);

    protected override void OnInitialized()
    {
        timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
        timer.Start();
    }

    private void OnTimerCallback()
    {
        _ = InvokeAsync(() =>
        {
            currentCount++;
            StateHasChanged();
        });
    }

    public void Dispose() => timer.Dispose();
}
@page "/counter-state-2"
@using System.Timers
@implements IDisposable

<PageTitle>Counter State 2</PageTitle>

<h1>Counter State Example 2</h1>

<p>
    This counter demonstrates <code>Timer</code> disposal.
</p>

<p>
    Current count: @currentCount
</p>

@code {
    private int currentCount = 0;
    private Timer timer = new(1000);

    protected override void OnInitialized()
    {
        timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
        timer.Start();
    }

    private void OnTimerCallback()
    {
        _ = InvokeAsync(() =>
        {
            currentCount++;
            StateHasChanged();
        });
    }

    public void Dispose() => timer.Dispose();
}
@page "/counter-state-2"
@using System.Timers
@implements IDisposable

<h1>Counter with <code>Timer</code> disposal</h1>

<p>
    Current count: @currentCount
</p>

@code {
    private int currentCount = 0;
    private Timer timer = new(1000);

    protected override void OnInitialized()
    {
        timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
        timer.Start();
    }

    private void OnTimerCallback()
    {
        _ = InvokeAsync(() =>
        {
            currentCount++;
            StateHasChanged();
        });
    }

    public void Dispose() => timer.Dispose();
}
@page "/counter-state-2"
@using System.Timers
@implements IDisposable

<h1>Counter with <code>Timer</code> disposal</h1>

<p>
    Current count: @currentCount
</p>

@code {
    private int currentCount = 0;
    private Timer timer = new(1000);

    protected override void OnInitialized()
    {
        timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
        timer.Start();
    }

    private void OnTimerCallback()
    {
        _ = InvokeAsync(() =>
        {
            currentCount++;
            StateHasChanged();
        });
    }

    public void Dispose() => timer.Dispose();
}
@page "/counter-state-2"
@using System.Timers
@implements IDisposable

<h1>Counter with <code>Timer</code> disposal</h1>

<p>
    Current count: @currentCount
</p>

@code {
    private int currentCount = 0;
    private Timer timer = new(1000);

    protected override void OnInitialized()
    {
        timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
        timer.Start();
    }

    private void OnTimerCallback()
    {
        _ = InvokeAsync(() =>
        {
            currentCount++;
            StateHasChanged();
        });
    }

    public void Dispose() => timer.Dispose();
}
@page "/counter-state-2"
@using System.Timers
@implements IDisposable

<h1>Counter with <code>Timer</code> disposal</h1>

<p>
    Current count: @currentCount
</p>

@code {
    private int currentCount = 0;
    private Timer timer = new Timer(1000);

    protected override void OnInitialized()
    {
        timer.Elapsed += (sender, eventArgs) => OnTimerCallback();
        timer.Start();
    }

    private void OnTimerCallback()
    {
        _ = InvokeAsync(() =>
        {
            currentCount++;
            StateHasChanged();
        });
    }

    public void Dispose() => timer.Dispose();
}

Belirli bir olay tarafından yeniden oluşturulan alt ağaç dışında bir bileşeni oluşturmak için

Kullanıcı arabirimi şunları içerebilir:

  1. Bir olayı tek bir bileşene dağıtma.
  2. Bazı durumu değiştirmek
  3. Etkinliği alan bileşenin alt öğelerinden biri olmayan tamamen farklı bir bileşeni yeniden render etme.

Bu senaryoyla başa çıkmanın bir yolu, genellikle birden çok bileşene eklenen bir bağımlılık ekleme (DI) hizmeti olarak bir durum yönetimi sınıfı sağlamaktır. Bir bileşen durum yöneticisinde bir yöntem çağırdığında, durum yöneticisi bağımsız bir bileşen tarafından alınan bir C# olayı oluşturur.

Durumu yönetme yaklaşımları için aşağıdaki kaynaklara bakın:

Durum yöneticisi yaklaşımı için C# olayları işleme işlem hattının Blazor dışındadır. Durum yöneticisinin olaylarına yanıt olarak yeniden render etmek istediğiniz diğer bileşenlerde StateHasChanged çağrısı yapın.

Durum yöneticisi yaklaşımı, System.Timers.Timer ile önceki bölümdeki benzer bir duruma benzerdir. Yürütme çağrı yığını genellikle işleyicinin eşitleme bağlamında kaldığından, çağrı InvokeAsync normalde gerekli değildir. Bu çağrı yalnızca mantık eşitleme bağlamından kaçarsa, örneğin bir InvokeAsync üzerinde ContinueWith çağırmak veya Task ile bir Task öğesi beklenirken, gereklidir. Daha fazla bilgi için İşleme ve olay işleme sistemiBlazor dışında bir öğeden çağrı alma bölümüne bakın.

Blazor Web App için WebAssembly yükleme ilerleme göstergesi

Yükleme ilerleme durumu göstergesi, proje şablonundan Blazor Web App oluşturulan bir uygulamada mevcut değildir. .NET'in gelecekteki bir sürümü için yeni bir yükleme ilerleme durumu göstergesi özelliği planlanıyor. Bu arada, bir uygulama bir yükleme ilerleme durumu göstergesi oluşturmak için özel kod benimseyebilir. Daha fazla bilgi için bkz . ASP.NET Core Blazor başlatma.