C# 如何停止无止境循环的任务
实际上这是一个非常简单的问题 如何使用停止按钮停止任务(无止境循环) 我的解决方案不起作用,使用开始按钮后用户界面冻结。因此,我认为我可以用bool-stop变量来解决它 我的代码:C# 如何停止无止境循环的任务,c#,multithreading,button,task,C#,Multithreading,Button,Task,实际上这是一个非常简单的问题 如何使用停止按钮停止任务(无止境循环) 我的解决方案不起作用,使用开始按钮后用户界面冻结。因此,我认为我可以用bool-stop变量来解决它 我的代码: using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading; using
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);
}));
}
}
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
名称空间WpfApp5_任务和Darstellu测试
{
///
///Interaktionslogik für MainWindow.xaml
///
公共部分类主窗口:窗口
{
私人停车场;
传输tr=新传输();
公共主窗口()
{
初始化组件();
}
私有无效列表视图1\u选择已更改(对象发送方,
选择ChangedEventArgs(e)
{
}
私有无效开始按钮单击(对象发送者,路由目标)
{
停止=错误;
ObservableCollection数据=新的ObservableCollection();
做
{
新任务(()=>{tr.GetData(Data);}).Start();
}while(stop!=true);
listView1.ItemsSource=数据;
}
公共作废停止按钮\单击(对象发送者,路由目标)
{
停止=真;
}
}
公共类转移
{
public void GetData(ObservableCollectiondata)
{
while(true)
{
对于(int i=0;i<2;i++)
{
对于(int j=0;j<3;j++)
{
int d=i+j;
Application.Current.Dispatcher.Invoke(
新操作(()=>
{
数据.添加(d);
}));
}
}
}
}
}
}
我还不明白这件事是否真的发生了改变。谢谢大家 创建一个新函数,将开始按钮中的内容放入该函数,单击该函数,然后设置一个线程来执行该函数。通过这种方式,主线程可以使UI保持活动状态,而后台的线程可以完成此工作。创建一个新函数,在开始按钮中放入内容\u单击该函数,然后设置一个线程来执行该函数。通过这种方式,您的主线程可以使UI保持活动状态,后台的线程可以执行此操作。首先,我们将使用为GetData方法添加取消支持,否则您无法真正取消此操作(您可以停止等待,但操作仍将继续,并继续向集合中添加项目,我们为什么要这样做?)
公共类传输
{
public void GetData(ObservableCollectiondata、CancellationToken CancellationToken)
{
while(true)
{
对于(int i=0;i<2;i++)
{
对于(int j=0;j<3;j++)
{
//如果要求取消操作,将抛出OperationCanceledException
cancellationToken.ThrowIfCancellationRequested();
数据.添加(d);
}
}
}
}
}
请注意,此处不需要使用Dispacher,因为此时集合未绑定到UI。然后我们可以使用取消主窗口中的操作,并在单击开始按钮时防止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();
}
}
公共部分类主窗口:窗口
{
私有传输_传输=新传输();
私有CancellationTokenSource _CancellationTokenSource=新的CancellationTokenSource();
公共主窗口()
{
初始化组件();
}
私有异步无效开始按钮单击(对象发送方,路由目标)
{
ObservableCollection数据=新的ObservableCollection();
尝试
{
等待任务。运行(()=>_transfer.GetData(Data,_cancellationTokenSource.Token);)
listView1.ItemsSource=数据;
}
捕捉(操作取消例外)
{
MessageBox.Show(“取消”);
}
}
私有无效停止按钮\单击(对象发送者,路由目标)
{
_cancellationTokenSource.Cancel();
}
}
您可以在中找到有关任务取消的更多信息。首先,我们将使用向GetData方法添加取消支持,否则您无法真正取消该操作(您可以停止等待,但该操作仍将继续并继续向集合中添加项,我们为什么要这样做?)
公共类传输
{
public void GetData(ObservableCollectiondata、CancellationToken CancellationToken)
{
while(true)
{
对于(int i=0;i<2;i++)
{
对于(int j=0;j<3;j++)
{
//如果要求取消操作,将抛出OperationCanceledException
cancellationToken.ThrowIfCancellationRequested();
数据.添加(d);
}
}
}
}
}
请注意,此处不需要使用Dispacher,因为此时集合未绑定到UI。然后我们可以使用取消主窗口中的操作,并在单击开始按钮时防止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();
}
}
公共部分类主窗口:窗口
{
私有传输_传输=新传输();
私有CancellationTokenSource _CancellationTokenSource=新的CancellationTokenSource();
公共M