TheBigBearNow Ответов: 2

В C# WPF с кнопку программы нажмите кнопку выполнить задание до следующего нажатия кнопки стоп


Всем привет,

Я создаю приложение WPF, где я хочу иметь глобальный bool im предполагая, что при первом нажатии кнопки Я установлю этот bool в true и хочу, чтобы он запускал задачу (непрерывно вызывал метод API) до тех пор, пока я снова не нажму кнопку и он не остановит ее. Как лучше всего это сделать?
private bool running = false;

private async void BtnTrade1_Buy_Click(object sender, RoutedEventArgs e)
{
    if (!running)
    {
        running = true;
    }
    else
        running = false;

    if (running)
    {
        RunningNrunnin(running);
        //tradeClient.GetTradeHistory();
    }
}

public void RunningNrunnin(bool running)
{
    if (running)
    {
        Task task = new Task(() =>
        {
            while (running)
            {
                GetTradeHistory();
                Thread.Sleep(2000);
            }
        });
        task.Start();
    }
}

Я согласен с использованием CancellationToken.
Как я могу использовать его с той же кнопкой? Я пробовал кучу вещей, но еще не сделал этого.
public async Task<int> GetTradeTest(CancellationToken cancelToken)
{
    int i = 0;
    // while(cancelToken == null)
    // {
        await Task.Delay(1000);
        i++;
    // }
    return i;
}

public Task<int> ExecuteOrCancel(CancellationToken token)
{
    Task<int> task = null;

    task = Task.Run(() =>
    {
        int result = 0;
        while (true)
        {
            if (token.IsCancellationRequested)
            {
                // throw new TaskCanceledException(task);
            }

            Thread.Sleep(1000);
            result++;
        }
        return result;
    });
    
    return task;
}

public async Task<int> GetTradeTest(CancellationToken cancelToken)
{
    int i = 0;
    // while(cancelToken == null)
    // {
        await Task.Delay(1000);
        i++;
    // }
    return i;
}

public Task<int> ExecuteOrCancel(CancellationToken token)
{
    Task<int> task = null;

    task = Task.Run(() =>
    {
        int result = 0;
        while (true)
        {
            if (token.IsCancellationRequested)
            {
                // throw new TaskCanceledException(task);
            }

            Thread.Sleep(1000);
            result++;
        }
        return result;
    });
    
    return task;
}

    try
    {
        cancellationToken = new CancellationTokenSource();
        lblTest.Content = "Starting...";
    
        // int counterTest = await tradeClient.GetTradeTest(cancellationToken.Token);
        var counterTest = tradeClient.ExecuteOrCancel(cancellationToken.Token);
        lblTest.Content = "Started: " + counterTest;
                
        // if (running)
        // {
            // tradeClient.RunningHarkins(running);
            // tradeClient.GetTradeHistory();
        // }
    }
    catch (Exception ex)
    {
        // MessageBox.Show(ex.Message);
        lblTest.Content = "Canceled";
    }
    // cancellationToken = null;
}


Что я уже пробовал:

Пробовал кодирование, потоковую обработку, задачи, используя глобальный bool, я могу заставить его включить true и false при нажатии кнопки, но тогда я не могу получить метод, чтобы продолжать проверять состояние bool во время его работы. Я знаю, что у меня есть хорошее начало, просто нужно несколько последних штрихов

2 Ответов

Рейтинг:
9

George Swan

Попробуйте сделать что-то вроде этого


private async void BtnTrade1_Buy_Click(object sender, RoutedEventArgs e)
{
    if(isRunning)
    {
        cts.Cancel();
        isRunning = false;
        return;
    }
    isRunning = true;
    cts = new CancellationTokenSource();
    try
    {
        await RunningNrunnin(cts.Token);
    }
    catch (OperationCanceledException ex)
    {
        //Do something here if necessary
    }

}


public async Task RunningNrunnin(CancellationToken token)
{
        while (true)
        {
            await Task.Run(() => GetTradeTest(token));
            await Task.Delay(2000, token);
        }
}


Рейтинг:
2

Garth J Lancaster

Я бы, вероятно, использовал cancellationtoken - посмотрите на них для идей

Как отменить задачу и ее дочерние элементы | Microsoft Docs[^]

Отмена асинхронных операций в C# | John Thiriet[^]