Предположим, что у вас есть датчик температуры, который можно прочитать через HTTP-запрос. Я хочу создать класс, в котором каждый экземпляр обновляет свою температуру раз в секунду, пока объект жив:
Код: Выделить всё
public class Sensor
{
public float Temperature { get; private set; }
private readonly string Uri;
public Sensor(string uri)
{
Uri = uri;
Task.Factory.StartNew(async () =>
{
while (true)
{
await UpdateTemperatureAsync();
await Task.Delay(1000);
}
}, TaskCreationOptions.LongRunning);
}
private async Task UpdateTemperatureAsync()
{
//just example code... not necessarily working
HttpClient client = new();
var response = await client.GetStringAsync(Uri);
Temperature = float.Parse(response);
}
}
Больше интуитивно, чем знания, я подумал, что было бы неплохо добавить токен отмены, чтобы убедиться, что задача обновления корректно отменен:
Код: Выделить всё
public class Sensor2 : IDisposable
{
public float Temperature { get; private set; }
private readonly string Uri;
private readonly Task UpdateTask;
CancellationTokenSource cts = new();
public Sensor2(string uri)
{
Uri = uri;
UpdateTask = Task.Factory.StartNew(async () =>
{
try
{
while (cts.IsCancellationRequested == false)
{
await Task.Delay(1000, cts.Token);
await UpdateTemperatureAsync();
}
}
catch (TaskCanceledException)
{
//expected end of task
}
catch (Exception ex)
{
//unexpected. Just print and try again
Console.WriteLine(ex.Message);
}
}, TaskCreationOptions.LongRunning);
}
private async Task UpdateTemperatureAsync()
{
HttpClient client = new();
var response = await client.GetStringAsync(Uri, cts.Token);
Temperature = float.Parse(response);
}
public void Dispose()
{
//try to kill the update task
cts.Cancel();
UpdateTask.Wait();
UpdateTask.Dispose();
//ready to be disposed
}
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... ith-object
Мобильная версия