每秒执行C#异步服务器操作

时间:2020-02-28 18:16:53

标签: c# asynchronous server timer client-server

我已经用C#成功创建了一个简单的服务器和客户端应用程序,可以在服务器和多个客户端之间进行异步通信,我使用了以下Microsoft文档来创建它:

https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-server-socket-example

https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-client-socket-example

它们都工作正常,但是我的问题是,我想每秒在服务器上执行一个动作,而我不知道执行此动作的最佳方法。我是否应该使用类似Timer类的方法来做到这一点?使用计时器是否以任何方式干扰服务器从客户端接收的呼叫?

2 个答案:

答案 0 :(得分:0)

是的,计时器是一种很好的方法。

对于Blazor组件Sprite我有类似的东西,每次计时器事件发生时,我都会在其中进行图像移动。

在我的情况下,我的订户是接口ISpriteSubscriber:

namespace DataJuggler.Blazor.Components.Interfaces
{

    #region interface ISpriteSubscriber
    /// <summary>
    /// This interface is used by the AnimationManager to notifiy callers that a refresh occurred.
    /// </summary>
    public interface ISpriteSubscriber
    {

        #region Methods

            #region Refresh()
            /// <summary>
            /// This method will call StateHasChanged to refresh the UI
            /// </summary>
            void Refresh();
            #endregion

            #region Register(Sprite sprite)
            /// <summary>
            /// This method is called by the Sprite to a subscriber so it can register with the subscriber, and 
            /// receiver events after that.
            /// </summary>
            void Register(Sprite sprite);

        #endregion

        #endregion

        #region Properties

            #region ProgressBar
            /// <summary>
            /// This is used so the ProgressBar is stored and available to the Subscriber after Registering
            /// </summary>
            ProgressBar ProgressBar { get; set; }
            #endregion

        #endregion

    }
    #endregion

}

public ISpriteSubscriber Subscriber { get; set; }

在启动事件中,我创建计时器:

public void Start()
{
    this.Timer = new Timer();
    this.Timer.Interval = this.interval;
    this.Timer.Elapsed += Timer_Elapsed;
    this.Timer.Start();
}

private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
    // if a subscriber (returns true if Subscriber != null)
    if (HasSubscriber)
    {
        // Notify Subscriber
        Subscriber.Refresh();
    }
}

public void Refresh()
{
    // do your actions here
}

public void Register(Sprite sprite)
{
    // If the sprite object exists
    if (NullHelper.Exists(sprite))
    {
        // if this is the RedCar
        if (sprite.Name == "RedCar")
        {
            // Set the RedCar
            RedCar = sprite;
        }
        else 
        {
            // Set the WhiteCar
            WhiteCar = sprite;
        }
    }
}

刷新事件是我移动图像的地方(在示例中为随机数)。

一个技巧当使用一个定时器,它经常关闭时,我通常会放置一些诸如NotificationInProgress标志之类的东西,或者万一一项操作花费的时间超过一秒。

也许在您的用例中,可以有多条消息,但是有时您需要等待一条消息完成才能完成下一条消息。

public bool NotificationInProgress { get; set; }

然后在通知我测试的订户

之前
if (!NotificationInProgress)
{
    // send your message.
}

如果您想查看一个开放源代码的Blazor示例项目,在这里演示该代码来自的简单动画,请访问:

https://github.com/DataJuggler/DataJuggler.Blazor.Components

enter image description here

也许它将为您提供一些有关如何安排项目的想法。

答案 1 :(得分:0)

我建议使用某种形式的Thread.Sleep或在带有Task.Delay的方法上调用await。请参见示例here