耗时工作和Progressbar
Time consuming work and Progressbar
我有一个包含项目的列表框,用户可以对项目执行一些操作,例如 New/Edit/Delete。但是,这可能需要一些时间,我想在执行基础操作时显示一个不确定的进度条。
我应该如何在 .NET 4.6 和 C# 6.0 中处理这个问题?
根据 this post,我应该使用基于任务的异步模式 (TAP)。线程中有许多可能的解决方案。
这仍然是首选方式吗?
在 C# 中,您可以使用工具箱中的进度条工具来显示不确定的时间。
要使用进度条,只需将其拖放到您的表单上即可。
现在来到主要问题,你想显示一个不确定的时间。
要在 progressBar 中显示进度,请使用计时器和以下代码:
int value = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if (value < 100)//value at 100 can be any large integer since indeterminant time
{
value++;
progressBar1.Value = value;
}
}
设置timer1.Interval = 100;
变量值是您为进度条设置的最大值。
由于您不知道时间,请将 progressBar 的最大值设置为 10000 或任何其他大值。
现在,当您进入您的功能时启用计时器(比如 New/Edit/Delete)并在您退出您的功能时禁用计时器
这里首先要了解的是,您应该在后台线程上执行 New/Edit/Delete 操作,以保持 UI 响应并使 ProgressBar
能够在完成这些操作所需的时间内更新。
off-load 某些工作到后台线程的首选和最简单的方法是使用任务并行库 (TPL) 并启动一个新任务。请记住,尽管 WPF 控件具有线程关联性,因此您只能在最初创建它们的线程上访问它们,即调度程序线程。
因此您可以通过将 ProgressBar
的 Visibility
属性 设置为 Visible
来实现这一点,启动一个执行实际 New/Edit/Delete 操作的任务然后在任务完成后再次将 Visibility
属性 设置回 Collapsed
:
C#:
pb.Visibility = Visibility.Visible;
Task.Run(()=>
{
//perform your long-running operation here...make sure that you don't access any UI elements
Save();
})
.ContinueWith(task =>
{
//this delegate will be executed back on the UI thread once the task has finished because of the scheduler returned from the TaskScheduler.FromCurrentSynchronizationContext() method...
pb.Visibility = Visibility.Collapsed;
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
XAML:
<ProgressBar x:Name="pb" IsIndeterminate="True" Visibility="Collapsed" />
我有一个包含项目的列表框,用户可以对项目执行一些操作,例如 New/Edit/Delete。但是,这可能需要一些时间,我想在执行基础操作时显示一个不确定的进度条。
我应该如何在 .NET 4.6 和 C# 6.0 中处理这个问题? 根据 this post,我应该使用基于任务的异步模式 (TAP)。线程中有许多可能的解决方案。
这仍然是首选方式吗?
在 C# 中,您可以使用工具箱中的进度条工具来显示不确定的时间。
要使用进度条,只需将其拖放到您的表单上即可。
现在来到主要问题,你想显示一个不确定的时间。 要在 progressBar 中显示进度,请使用计时器和以下代码:
int value = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if (value < 100)//value at 100 can be any large integer since indeterminant time
{
value++;
progressBar1.Value = value;
}
}
设置timer1.Interval = 100;
变量值是您为进度条设置的最大值。
由于您不知道时间,请将 progressBar 的最大值设置为 10000 或任何其他大值。 现在,当您进入您的功能时启用计时器(比如 New/Edit/Delete)并在您退出您的功能时禁用计时器
这里首先要了解的是,您应该在后台线程上执行 New/Edit/Delete 操作,以保持 UI 响应并使 ProgressBar
能够在完成这些操作所需的时间内更新。
off-load 某些工作到后台线程的首选和最简单的方法是使用任务并行库 (TPL) 并启动一个新任务。请记住,尽管 WPF 控件具有线程关联性,因此您只能在最初创建它们的线程上访问它们,即调度程序线程。
因此您可以通过将 ProgressBar
的 Visibility
属性 设置为 Visible
来实现这一点,启动一个执行实际 New/Edit/Delete 操作的任务然后在任务完成后再次将 Visibility
属性 设置回 Collapsed
:
C#:
pb.Visibility = Visibility.Visible;
Task.Run(()=>
{
//perform your long-running operation here...make sure that you don't access any UI elements
Save();
})
.ContinueWith(task =>
{
//this delegate will be executed back on the UI thread once the task has finished because of the scheduler returned from the TaskScheduler.FromCurrentSynchronizationContext() method...
pb.Visibility = Visibility.Collapsed;
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
XAML:
<ProgressBar x:Name="pb" IsIndeterminate="True" Visibility="Collapsed" />