我怎样才能停止 Task.Run()?
How can I stop the Task.Run()?
我对线程的概念比较陌生,我想在我的应用程序中使用 Task
,它是 Thread
的一个组件,因为保存任务需要时间来执行。
这是我的代码:
private void SaveItem(object sender, RoutedEventArgs e)
{
// Button Save Click ( Save to the database )
Task.Run(() =>
{
var itemsS = Gridview.Items;
Dispatcher.Invoke(() =>
{
foreach (ItemsModel item in itemsS)
{
PleaseWaittxt.Visibility = Visibility.Visible;
bool testAdd = new Controller().AddItem(item);
if (testAdd)
Console.WriteLine("Add true to Items ");
else
{
MessageBox.Show("Add failed");
return;
}
}
PleaseWaittxt.Visibility = Visibility.Hidden;
});
});
MessageBox.Show("Save Done");
// update the gridView
var results = new Controller().GetAllItems();
Gridview.ItemsSource = null;
Gridview.ItemsSource = results;
Gridview.Items.Refresh();
}
问题是当我保存所有项目时,我在数据库中得到了重复的数据。否则,ItemsS
的计数固定为300,但保存后,我得到了600,
是否Task.Run()
重复了保存到数据库的任务?
注意: 我正在处理 UI 项目(WPF 桌面应用程序)
我认为您需要与此类似的东西。
我很快就把它搞定了,但我希望它足以让你自己尝试修复。
private async void SaveItem(object sender, RoutedEventArgs e)
{
try {
var itemsS = GridviewServices.Items.ToList(); // to list makes shallow copy
await Task.Run(() => {
foreach (ItemsModel item in itemsS)
{
bool testAdd = new Controller().AddItem(item);
}
});
// Dont update ui in task.run, because only the ui thread may access UI items
// Do so here - after the await. (or use dispatcher.invoke).
GridviewServices.Items.Clear();
GridviewServices.Items = itemsS;
} catch { ... } // Handle exceptions, log them or something. Dont throw in async void!
}
我也认为这会起作用:
private async void SaveItem(object sender, RoutedEventArgs e)
{
// Button Save Click ( Save to the database )
var itemsS = GridviewServices.Items;
await Task.Run(() =>
{
foreach (ItemsModel item in itemsS)
{
Dispatcher.Invoke(() => {PleaseWaittxt.Visibility = Visibility.Visible;})
bool testAdd = new Controller().AddItem(item);
if (testAdd)
Console.WriteLine("Add true to Items ");
else
{
MessageBox.Show("Add failed");
return;
}
}
Dispatcher.Invoke(() => {PleaseWaittxt.Visibility = Visibility.Hidden;})
});
MessageBox.Show("Save Done");
// update the gridView
var results = new Controller().GetAllItems();
Gridview.ItemsSource = null;
Gridview.ItemsSource = results;
Gridview.Items.Refresh();
}
您 运行 遇到的问题是因为您正在执行的任务不是 运行 并行,而是与应用程序的其余部分同步。
当您在 UI 应用程序的后台执行 运行 CPU 密集型任务时,您需要使用实际线程或 async/await - 这就是您尝试使用代码的方式。
你想要做的是类似这样的事情:
private async void SaveItem(object sender, RoutedEventArgs e) => await Task.Run(
/*optionally make this async too*/() => {
// Execute your CPU-intensive task here
Dispatcher.Invoke(() => {
// Handle your UI updates here
});
});
这只是一般性概述,我不知道您的确切用例,但这应该能让您朝着正确的方向开始。
使用 Lambdas 等时要厌烦的一件事是闭包。
如果您的应用程序倾向于使用大量内存,您可能需要重新考虑调用树的结构并尽量减少 运行 应用程序中的闭包。
我对线程的概念比较陌生,我想在我的应用程序中使用 Task
,它是 Thread
的一个组件,因为保存任务需要时间来执行。
这是我的代码:
private void SaveItem(object sender, RoutedEventArgs e)
{
// Button Save Click ( Save to the database )
Task.Run(() =>
{
var itemsS = Gridview.Items;
Dispatcher.Invoke(() =>
{
foreach (ItemsModel item in itemsS)
{
PleaseWaittxt.Visibility = Visibility.Visible;
bool testAdd = new Controller().AddItem(item);
if (testAdd)
Console.WriteLine("Add true to Items ");
else
{
MessageBox.Show("Add failed");
return;
}
}
PleaseWaittxt.Visibility = Visibility.Hidden;
});
});
MessageBox.Show("Save Done");
// update the gridView
var results = new Controller().GetAllItems();
Gridview.ItemsSource = null;
Gridview.ItemsSource = results;
Gridview.Items.Refresh();
}
问题是当我保存所有项目时,我在数据库中得到了重复的数据。否则,ItemsS
的计数固定为300,但保存后,我得到了600,
是否Task.Run()
重复了保存到数据库的任务?
注意: 我正在处理 UI 项目(WPF 桌面应用程序)
我认为您需要与此类似的东西。 我很快就把它搞定了,但我希望它足以让你自己尝试修复。
private async void SaveItem(object sender, RoutedEventArgs e)
{
try {
var itemsS = GridviewServices.Items.ToList(); // to list makes shallow copy
await Task.Run(() => {
foreach (ItemsModel item in itemsS)
{
bool testAdd = new Controller().AddItem(item);
}
});
// Dont update ui in task.run, because only the ui thread may access UI items
// Do so here - after the await. (or use dispatcher.invoke).
GridviewServices.Items.Clear();
GridviewServices.Items = itemsS;
} catch { ... } // Handle exceptions, log them or something. Dont throw in async void!
}
我也认为这会起作用:
private async void SaveItem(object sender, RoutedEventArgs e)
{
// Button Save Click ( Save to the database )
var itemsS = GridviewServices.Items;
await Task.Run(() =>
{
foreach (ItemsModel item in itemsS)
{
Dispatcher.Invoke(() => {PleaseWaittxt.Visibility = Visibility.Visible;})
bool testAdd = new Controller().AddItem(item);
if (testAdd)
Console.WriteLine("Add true to Items ");
else
{
MessageBox.Show("Add failed");
return;
}
}
Dispatcher.Invoke(() => {PleaseWaittxt.Visibility = Visibility.Hidden;})
});
MessageBox.Show("Save Done");
// update the gridView
var results = new Controller().GetAllItems();
Gridview.ItemsSource = null;
Gridview.ItemsSource = results;
Gridview.Items.Refresh();
}
您 运行 遇到的问题是因为您正在执行的任务不是 运行 并行,而是与应用程序的其余部分同步。
当您在 UI 应用程序的后台执行 运行 CPU 密集型任务时,您需要使用实际线程或 async/await - 这就是您尝试使用代码的方式。
你想要做的是类似这样的事情:
private async void SaveItem(object sender, RoutedEventArgs e) => await Task.Run(
/*optionally make this async too*/() => {
// Execute your CPU-intensive task here
Dispatcher.Invoke(() => {
// Handle your UI updates here
});
});
这只是一般性概述,我不知道您的确切用例,但这应该能让您朝着正确的方向开始。
使用 Lambdas 等时要厌烦的一件事是闭包。 如果您的应用程序倾向于使用大量内存,您可能需要重新考虑调用树的结构并尽量减少 运行 应用程序中的闭包。