代码之家  ›  专栏  ›  技术社区  ›  Chris

在TopShelf中使用异步WhenStarted和WhenStopped方法

  •  1
  • Chris  · 技术社区  · 7 年前

    one mentionon their github pages 声明不应以这种方式使用async。

    但是,尽管如此,它的编译和运行(大部分)还可以。那么这是正确的还是应该使用 .Wait() 相反呢?

    var host = HostFactory.New(hostConfig =>
    {
        hostConfig.Service<StreamClient>(serviceConfig =>
        {
            serviceConfig.ConstructUsing(name => new StreamClient());
            serviceConfig.WhenStarted(async tc => await tc.Start());
            serviceConfig.WhenStopped(async tc => await tc.Stop());
        });
    
        hostConfig.RunAsLocalSystem();
    
        hostConfig.SetDescription("Stream Client Service");
        hostConfig.SetDisplayName("Stream Client Service");
        hostConfig.SetServiceName("StreamClientService");
    });
    
    host.Run();
    

    @Nkosi问方法签名是什么样子的,它们是异步的,并且启动内部客户机和进程。

    public async Task Start()
    {
        // Dont start again if we are already running, or if we are already in the starting state
        if (this.Running || this.Starting)
        {
            return;
        }
    
        await this.slackService.SendSlackServiceEvent(ServiceEventType.Starting, serviceName, applicationVersion);
    
        this.Starting = true;
        this.Stopping = false;
    
        var configurationBuilder = new ClientConfigurationBuilder();
    
        ClientConfiguration clientConfiguration;
        if (Constants.UseLocalConnection)
        {
            await this.OnClientDebugMessage($"Using Local Connection");
            clientConfiguration = configurationBuilder.CreateLocalConfiguration();
        }
        else
        {
            await this.OnClientDebugMessage($"Using SQL Connection");
            clientConfiguration = configurationBuilder.CreateSqlConfiguration();
        }
    
        this.ClusterGrainClient = await this.StartClient(clientConfiguration);
    
        if (this.ClusterGrainClient == null)
        {
            using (ConsoleColours.TextColour(ConsoleColor.Red))
            {
                await this.OnClientDebugMessage($"Cluster client null, aborting!");
            }
    
            return;
        }
    
        this.Running = true;
    
        await this.OnClientStarted();
        await this.slackService.SendSlackServiceEvent(ServiceEventType.Started, serviceName, applicationVersion);
        this.Starting = false;
    
    }
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   Nkosi    7 年前

    你基本上是在做一个 async void

    参考 Async/Await - Best Practices in Asynchronous Programming

    将start和stop方法转换为引发可以在内部等待的异步事件的同步方法。

    public void Start() {
        Started += OnStarted; //subscribe to event
        Started(this, EventArgs.Empty); //raise event
    }
    
    private event EventHandler Started = delegate { };
    
    private async void OnStart(object sender, EventArgs args) {
        Started -= OnStarted;        
        await StartAsync();
    }
    
    public async Task StartAsync() {
        // ...
    }
    

    然后正常启动

    serviceConfig.WhenStarted(_ => _.Start());
    

        2
  •  5
  •   Paulo Morgado    7 年前

    我自己从来没有试过,但你可以这样试:

    public void Start() => this.StartAsync().GetAwaiter().GetResult();
    public void Stop() => this.Stop().GetAwaiter().GetResult();
    
    public async Task StartAsync()
    {
        // ...
    }
    
    public async Task StopAsync()
    {
        // ...
    }
    
    推荐文章