• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DemoBytom / DemoEngine / 23164193691

16 Mar 2026 08:22PM UTC coverage: 33.457% (+4.1%) from 29.327%
23164193691

push

coveralls.net

web-flow
Merge pull request #528 from DemoBytom/feature/ValueResults

Adds `ValueResult<T, E>`

1263 of 3775 relevant lines covered (33.46%)

0.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Demo.Engine.Core/Services/ServiceBase.cs
1
// Copyright © Michał Dembski and contributors.
2
// Distributed under MIT license. See LICENSE file in the root for more information.
3

4
using System.Reflection;
5
using System.Runtime.InteropServices;
6
using Microsoft.Extensions.Hosting;
7
using Microsoft.Extensions.Logging;
8

9
namespace Demo.Engine.Core.Services;
10

11
public abstract class ServiceBase : IHostedService, IDisposable
12
{
13
    private bool _disposedValue;
14
    protected readonly ILogger _logger;
15
    private readonly IHostApplicationLifetime _applicationLifetime;
16
    private Task? _executingTask;
17
    private bool _stopRequested;
18

19
    protected readonly string _version = Assembly
×
20
        .GetEntryAssembly()
×
21
        ?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
×
22
        ?.InformationalVersion ?? "0.0.0";
×
23

24
    private readonly string _serviceName;
25

26
    protected ServiceBase(
×
27
        string serviceName,
×
28
        ILogger logger,
×
29
        IHostApplicationLifetime applicationLifetime)
×
30
    {
31
        _logger = logger;
×
32
        _applicationLifetime = applicationLifetime;
×
33
        _serviceName = serviceName;
×
34
    }
×
35

36
    public Task StartAsync(CancellationToken cancellationToken)
37
    {
38
        _logger.LogServiceIsStarting(_serviceName, _version);
×
39
        _executingTask = DoWorkAsync();
×
40

41
        //If task is completed return it,
42
        //otherwise return CompletedTask since DoWork is running
43
        return _executingTask.IsCompleted
×
44
            ? _executingTask
×
45
            : Task.CompletedTask;
×
46
    }
47

48
    public async Task StopAsync(CancellationToken cancellationToken)
49
    {
50
        _logger.LogServiceStopping(_serviceName);
×
51

52
        _stopRequested = true;
×
53
        if (_executingTask is null)
×
54
        {
55
            return;
×
56
        }
57

58
        _ = await Task.WhenAny(
×
59
            _executingTask,
×
60
            Task.Delay(Timeout.Infinite, cancellationToken));
×
61
    }
×
62

63
    private Task DoWorkAsync()
64
    {
65
        //Starts the work one a new STA thread so that Windows.Forms work correctly
66
        var tcs = new TaskCompletionSource<object?>(
×
67
            TaskCreationOptions.RunContinuationsAsynchronously);
×
68
        var thread = new Thread(async () =>
×
69
        {
×
70
            try
×
71
            {
×
72
                await DoWork();
×
73
                tcs.SetResult(null);
×
74
            }
×
75
            catch (Exception ex)
×
76
            {
×
77
                _logger.LogServiceFailedWithError(ex, _serviceName);
×
78
                tcs.SetException(ex);
×
79
            }
×
80
        });
×
81
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
×
82
        {
83
            //Can only by set on the Windows machine. Doesn't work on Linux/MacOS
84
            thread.SetApartmentState(ApartmentState.STA);
×
85
        }
86

87
        thread.Start();
×
88
        return tcs.Task;
×
89
    }
90

91
    private async Task DoWork()
92
    {
93
        _logger.LogServiceIsWorking(_serviceName, _version);
×
94
        try
95
        {
96
            await ExecuteAsync();
×
97
        }
×
98
        finally
99
        {
100
            //If StopAsync was already called, no reason to call it again
101
            if (!_stopRequested)
×
102
            {
103
                _applicationLifetime.StopApplication();
×
104
            }
105
        }
106
    }
×
107

108
    protected abstract Task ExecuteAsync();
109

110
    #region IDisposable
111

112
    protected virtual void Dispose(bool disposing)
113
    {
114
        if (!_disposedValue)
×
115
        {
116
            if (disposing)
×
117
            {
118
                _applicationLifetime.StopApplication();
×
119
            }
120
            _disposedValue = true;
×
121
        }
122
    }
×
123

124
    public void Dispose()
125
    {
126
        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
127
        Dispose(disposing: true);
×
128
        GC.SuppressFinalize(this);
×
129
    }
×
130

131
    #endregion IDisposable
132
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc