Почему моя задача не может быть отменена и воссоздана несколько раз? - PullRequest
0 голосов
/ 04 февраля 2020

Требование: несколько устройств BLE (устройство) будут транслировать рекламные данные каждую секунду, нам нужно получить данные и указать (ЗЕЛЕНЫЙ) конкретное устройство в мобильном приложении. Если какой-либо из Аппаратных средств прекращает вещание, мне нужно изменить цвет КРАСНЫЙ через 30 сек c. Если оборудование отправляет пакет до 30 секунд c, нам нужно выполнить сброс задачи и сохранить только ЗЕЛЕНЫЙ статус.

Текущий подход: мы создали задачу, которая будет ожидать 30 секунд c и измените цвет устройства на красный. Как и когда мы получаем данные новые данные с того же оборудования, мы отменяем запущенную задачу и создаем новую.

Постановка задачи: Текущий подход работает, как ожидается, менее 1 минуты. После этого задания отмена не произойдет, как ожидалось.

Пожалуйста, предложите.

var deviceDetectedDict = new Dictionary<string,CancellationTokenSource>();

if (deviceDetectedDict.ContainsKey(seatName))
{
    CancellationTokenSource cTokenSource = deviceDetectedDict[seatName];
    if (cTokenSource != null)
    {
        cTokenSource.Cancel();
        deviceDetectedDict.Remove(seatName);
        cTokenSource.Dispose();
        CreateTask(lockedseatIDUIIV, seatName);
    }
}
else 
{
    CreateTask(lockedseatIDUIIV, seatName); 
}

private void CreateTask(UIImageView _seatIDUIIV, string _seatID)
{
    CancellationTokenSource cts = new CancellationTokenSource();
    deviceDetectedDict.Add(_seatID, cts);
    Task myTask = new Task(() => 
        CreateTaskWithTimer(_seatIDUIIV, cts.Token, _seatID));
    myTask.Start();
}

private async void CreateTaskWithTimer(UIImageView view, CancellationToken ct, string seat)
{
    try
    {
        Console.WriteLine("Thread ID created = " + Thread.CurrentThread.ManagedThreadId);

        BeginInvokeOnMainThread(() =>
        {
            ChangeImageToLocked(ImageGREEN);
        });

        await Task.Delay(30000, ct);

        BeginInvokeOnMainThread(() =>
        {
            ChangeImageToUnLocked(ImageRED);
        });    
    }
    catch (OperationCanceledException oc)
    {
       Console.WriteLine( seat + " Task cancelled :"+ ""+ oc.Message);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

1 Ответ

0 голосов
/ 04 февраля 2020

У вашей задачи действительно плохой дизайн.

Вот как это может выглядеть

private async Task CreateTaskWithTimerAsync( UIImageView seatImageView, CancellationToken ct,string seat )
{
    ChangeImageToLocked(ImageGREEN);
    await Task.Delay( 30000, ct );
    ChangeImageToUnLocked(ImageRED);
}

private void CreateTask(UIImageView _seatIDUIIV, string _seatID)
{
    CancellationTokenSource cts = new CancellationTokenSource();
    deviceDetectedDict.Add(_seatID, cts);
    var _ = CreateTaskWithTimerAsync(_seatIDUIIV, cts.Token, _seatID));
}
...