实际上这是一个非常简单的问题。
如何使用停止按钮停止我的任务(无限循环)?
我的解决方案不起作用,用户界面在我使用开始按钮后被冻结。因此,我认为我可以使用bool stop变量
来解决它我的代码:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp5_Task_und_darstellun_test
{
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private bool stop;
Transfer tr = new Transfer();
public MainWindow()
{
InitializeComponent();
}
private void listView1_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
}
private void StartButton_Click(object sender, RoutedEventArgs e)
{
stop = false;
ObservableCollection<int> Data = new ObservableCollection<int>();
do
{
new Task(() => { tr.GetData(Data); }).Start();
} while (stop != true);
listView1.ItemsSource = Data;
}
public void StopButton_Click(object sender, RoutedEventArgs e)
{
stop = true;
}
}
public class Transfer
{
public void GetData(ObservableCollection<int>data)
{
while (true)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
int d = i + j;
Application.Current.Dispatcher.Invoke(
new Action(() =>
{
data.Add(d);
}));
}
}
}
}
}
}
我还没有理解INotifyPropertyChanged的问题。非常感谢你们。
答案 0 :(得分:1)
首先我们将使用CacellationToken为GetData方法添加取消支持,否则你无法真正取消操作(你可以停止等待它,但操作仍会计算并继续向集合中添加项目为什么我们想要那个?)
public class Transfer
{
public void GetData(ObservableCollection<int>data, CancellationToken cancellationToken)
{
while (true)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
//Will throw OperationCanceledException if the operation was asked to be canceled
cancellationToken.ThrowIfCancellationRequested();
data.Add(d);
}
}
}
}
}
请注意,我们不需要在此处使用Dispacher,因为此时集合不受UI限制。
然后我们可以使用CancellatonTokenSource和async and await取消主窗口中的操作,以防止UI在我们点击开始按钮时冻结:
public partial class MainWindow : Window
{
private Transfer _transfer = new Transfer();
private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource ();
public MainWindow()
{
InitializeComponent();
}
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<int> Data = new ObservableCollection<int>();
try
{
await Task.Run(() => _transfer.GetData(Data, _cancellationTokenSource.Token);)
listView1.ItemsSource = Data;
}
catch(OperationCanceledException ex)
{
MessageBox.Show("Canceled");
}
}
private void StopButton_Click(object sender, RoutedEventArgs e)
{
_cancellationTokenSource.Cancel();
}
}
您可以在MSDN中找到有关“任务取消”的更多信息。
答案 1 :(得分:0)
创建一个新函数,在该函数的StartButton_Click中放置什么,然后设置一个线程来执行该函数。通过这种方式,您的主线程可以保持UI的活动,并且后台的线程可以正常工作。