我如何在 Blazor 中创建计时器组件并从组件或其他页面外部启动它

How I can Create a timer component in Blazor and start it from outside of component or other page

如何在 Blazor 中创建计时器组件并从组件外部或其他页面启动它。 我的组件代码如下:

@using LosacoWeb.Shared.Enumes
@using System.Timers
@implements IDisposable

@if (BlnVisiblaState == true)
{
    <section>

        <div class="container">
            <div class="row">
                <div class="col-lg-8 offset-lg-2">
                    <div>

                        <div class="alert shortcode_modules" style="border-color:lightblue;border-style: solid;border-width: thin;padding: 5px;margin: 5px 10px;border-radius: 5px;" role="alert">
                            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                <span class="icon-close" aria-hidden="true"></span>
                            </button>
                            <div class="modules__title">
                                <h3 dir="rtl" style="float:right;">@MessageTitle</h3>
                            </div>

                            <div class="modules__content">
                                @if (message == MessagePanelColor.primary)
                                {
                                    <div class="alert alert-primary" role="alert">
                                        <strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
                                        @*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                                <span class="icon-close" aria-hidden="true"></span>
                                            </button>*@
                                    </div>
                                }
                                @if (message == MessagePanelColor.secondary)
                                {
                                    <div class="alert alert-secondary" role="alert">
                                        <strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
                                        @*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                                <span class="icon-close" aria-hidden="true"></span>
                                            </button>*@
                                    </div>
                                }
                                @if (message == MessagePanelColor.success)
                                {
                                    <div class="alert alert-success" role="alert">
                                        <strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
                                        @*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                                <span class="icon-close" aria-hidden="true"></span>
                                            </button>*@
                                    </div>
                                }
                                @if (message == MessagePanelColor.info)
                                {
                                    <div class="alert alert-info" role="alert">
                                        <strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
                                        @*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                                <span class="icon-close" aria-hidden="true"></span>
                                            </button>*@
                                    </div>
                                }
                                @if (message == MessagePanelColor.warning)
                                {
                                    <div class="alert alert-warning" role="alert">
                                        <strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
                                        @*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                                <span class="icon-close" aria-hidden="true"></span>
                                            </button>*@
                                    </div>
                                }
                                @if (message == MessagePanelColor.danger)
                                {
                                    <div class="alert alert-danger" role="alert">
                                        <strong>@MessageShortDescription !!!</strong>@MessageBuddyLongDescription
                                        @*<button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                                <span class="icon-close" aria-hidden="true"></span>
                                            </button>*@
                                    </div>
                                }
                            </div>
                        </div>
                    </div>
                    <!-- end .col-md-6 -->
                </div>
                <!-- end .row -->
            </div>
            <!-- end .container -->
        </div>
    </section>
}
@code
{
    [Parameter]
    public Boolean BlnVisiblaState { get; set; }
    [Parameter]
    public String MessageTitle { get; set; }
    [Parameter]
    public String MessageShortDescription { get; set; }
    [Parameter]
    public String MessageBuddyLongDescription { get; set; }
    [Parameter]
    public LosacoWeb.Shared.Enumes.MessagePanelColor message { get; set; }

    Timer timer;
    int int_Counter = 0;

    public async Task ChangeState()
    {
        BlnVisiblaState = !BlnVisiblaState;
        timer.Stop();
    }

    protected override void OnInitialized()
    {
        timer = new Timer();
        timer.Interval = 1000;
        timer.Elapsed += TimerOnElapsed;
        timer.Start();
    }

    public async Task StasrtTimer()
    {
        timer = new Timer();
        timer.Interval = 1000;
        timer.Elapsed += TimerOnElapsed;
        timer.Start();
    }

    private void TimerOnElapsed(object sender, ElapsedEventArgs e)
    {
        if (int_Counter >= 5)
        {
            ChangeState();
            //Console.WriteLine(DateTime.Now.Ticks.ToString());
            StateHasChanged();
        }
        int_Counter++;
        Console.WriteLine(int_Counter.ToString());
    }

    public void Dispose()
    {
        if (timer != null)
        {
            timer.Dispose();
        }
    }
}

但我不知道如何从其他 Blazor 页面启动和停止计时器。此页面应显示按摩,并在 6 秒后隐藏。但我无法从外部页面启动计时器。感谢您的关注。

您实际上并没有像问题标题中的 post 那样创建计时器组件。 您真正想要的是创建一个服务 class,您可以将其注入到您的组件中。您可以通过多种方式做到这一点,并提供您想要的任何功能。

您的定时器服务 class 可能看起来像这样 (Warning you should also implement the IDisposable interface to dispose the timer in order to prevent memory leaks):

using System.Threading.Tasks;
using System.Timers;

public class BlazorTimer
    {
        private Timer _timer;
        private int count;
        private int end;
        internal void SetTimer(double interval, int start, int _end)
        {
            _timer = new Timer(interval);
            _timer.Elapsed += Counter;
            _timer.Enabled = true;
            count = start;
            end = _end;
            _timer.Start();
        }
        
        private void Counter(object sender, ElapsedEventArgs e)
        {
            count++;
            if (count >= end)
            {
                ((Timer)sender).Stop();
                TimerEventArgs args = new TimerEventArgs { Count = count };
                OnCountCompleted(args);
            }
        }
        

        protected virtual void OnCountCompleted(TimerEventArgs args)
        {
            EventHandler<TimerEventArgs> handler = CountCompleted;
            if (handler != null)
            {
                handler(this, args);
            }
        }

        public event EventHandler<TimerEventArgs> CountCompleted;
    }
    
    public class TimerEventArgs : EventArgs
    {
        public int Count { get; set; }
    }

Program.cs

public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("#app");

           //...Code removed for brevity's sake...

            builder.Services.AddScoped(config =>
            {
                var blazorTimer = new BlazorTimer();
                blazorTimer.SetTimer(1000, 100, 110);
                return blazorTimer;
            });

            await builder.Build().RunAsync();
        }
    }

用法

@page "/counter"

@inject BlazorTimer Timer
@implements IDisposable

<h1>Counter</h1>
    @count.ToString()

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

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

    @code {
        private int currentCount = 0;

        private void IncrementCount()
        {
            currentCount++;
        }

protected override void OnInitialized()
        {
          
            Timer.CountCompleted += NotifyCompleted;

            base.OnInitialized();
        }


        int count = 0;
        private void NotifyCompleted(object sender, TimerEventArgs args)
        {

            count = args.Count;
            InvokeAsync(() => { StateHasChanged(); });
        }


        public void Dispose()
        {
            Timer.CountCompleted -= NotifyCompleted;
        }
    }

注意:正如我之前所说,您可以通过多种方式进行编码,例如,您不必在注入 Timer 时设置间隔、开始和结束的值(Main 方法),您可以对其进行编码以从 OnInitialised(Async) 方法对中的组件获取这些值。