C#WPF程序按钮单击运行任务,直到另一个按钮单击停止

问题描述 投票:0回答:1

我正在创建一个WPF应用,我想在其中拥有一个全局布尔值,在第一个按钮上单击,将其设置为true,并希望它运行任务(连续调用API方法),直到单击为止。再次按下该按钮,它将停止它。最好的方法是什么?私人布尔运行=假;

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();
            }
        }
c# wpf multithreading
1个回答
0
投票

您可以通过Task暂停和恢复AutoResetEvent。简要示例如下

Task _taskGetTradeHistories;
AutoResetEvent _ewh = new AutoResetEvent(true);
public volatile bool _paused = false;

public Task RunningNrunnin(Action action)
{
    return Task.Run(() =>
    {
        while (true)
        {
            if (_paused)
            {
                _ewh.WaitOne();
            }

            label1.Invoke(action);
            SpinWait.SpinUntil(() => false, TimeSpan.FromSeconds(1));
        }
    });
}

private void BtnTrade1_Buy_Click(object sender, EventArgs e)
{
    if (_taskGetTradeHistories != null && !_paused)
    {
        _paused = true;
    }
    else
    {
        _ewh.Set();
        _paused = false;
    }

    if (_taskGetTradeHistories == null || _taskGetTradeHistories.IsCompleted)
    {
        _taskGetTradeHistories = RunningNrunnin(() =>
        {
            GetTradeHistory();
        });
    }
}

0
投票

我制作了一个小的控制台测试应用程序来对此进行测试,因此我不得不更改方法签名(静态),并且无法在控制台上使用ButtonClick。我通过在程序化的“按钮单击”之间放置睡眠来模拟按钮单击。

这可能会让您入门。

    static void Main(string[] args)
    {
      #if (DEBUG)
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("!!Debug!!");
        Console.ForegroundColor = ConsoleColor.Green;
        Console.WriteLine($"No. Processors: {System.Environment.ProcessorCount}");
        Console.ResetColor();
      #else
        Console.WriteLine("!!Release!!");
      #endif

      Console.WriteLine(“Start”);
        BtnTrade1_Buy_Click();
        System.Threading.Thread.Sleep(1000);
        BtnTrade1_Buy_Click();
        System.Threading.Thread.Sleep(1000);
        BtnTrade1_Buy_Click();
        System.Threading.Thread.Sleep(1000);
        BtnTrade1_Buy_Click();
        System.Threading.Thread.Sleep(1000);
        BtnTrade1_Buy_Click();
        System.Threading.Thread.Sleep(1000);
        BtnTrade1_Buy_Click();
      Console.WriteLine(“END”);
    }


    private static bool isRunning = false;
    static int clickCounter = 0;
    static int iterationsCounter = 0;
    private static async Task BtnTrade1_Buy_Click()
    {
        iterationsCounter = 0;
        isRunning = !isRunning;
        Console.WriteLine($"Ha: {isRunning} {clickCounter++}");
        await RunningNrunnin();
    }



    private static async Task RunningNrunnin()
    {
        await Task.Run(() => Runit());
    }


    private static void Runit()
    {
        while (isRunning)
        {
            GetTradeHistory();
            System.Threading.Thread.Sleep(100);
        }
    }


    private static void GetTradeHistory()
    {
        Console.WriteLine($"Hello Test {iterationsCounter++}");
    }

当然,您不需要所有计数器和Console.WriteLine()东西。它们在那里可以让您直观地看到正在发生的事情。

让我知道是否需要更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.