希望在UI中持续运行进度条,直到我们收到服务响应
本文关键字:我们 响应 服务 UI 运行 希望 | 更新日期: 2023-09-27 18:06:20
我想为WPF应用程序中的连续进度条分配一个新线程,以便它在点击UI按钮后连续运行,直到我收到服务响应。
我做了如下代码,但进度条(MclarenServerCecksProgressBar)似乎不工作
MclarenServerCecksProgressBar.Visibility = Visibility.Visible;
var uiThread = new Thread(() =>
{
progressBarDisptacher = MclarenServerCecksProgressBar.Dispatcher;
// allowing the main UI thread to proceed
System.Windows.Threading.Dispatcher.Run();
});
uiThread.SetApartmentState(ApartmentState.STA);
uiThread.IsBackground = true;
uiThread.Start();
string[] servicesss = getServices(servername,server);
DataTable dtd = esd.getListOfServices(servername, usrid.Text.ToString(),
userpass.Password.ToString(), servicesss);
MclarenServerCecksProgressBar.Visibility = Visibility.Hidden;
请安排建议我实现这一点,任何其他指针将大有帮助。
我不明白你的代码中进度条值是如何设置的。我也不太明白你为什么用这个线程黑客。我举了一个例子,如果我理解你的问题正确的话,我是如何用进度条做这件事的。
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525">
<Grid>
<ProgressBar Height="10"
HorizontalAlignment="Left"
Margin="12,12,0,0"
Name="progressBar1"
VerticalAlignment="Top"
Width="100"
Visibility="Hidden" />
<Button Content="Button"
Height="23"
HorizontalAlignment="Left"
Margin="30,54,0,0"
Name="button1"
VerticalAlignment="Top"
Width="75"
Click="button1_Click" />
</Grid>
</Window>
using System;
using System.Threading;
using System.Windows;
namespace WpfApplication5 {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
void button1_Click(object sender, RoutedEventArgs e) {
progressBar1.Visibility = Visibility.Visible;
Action method = () => {
Action<int> method2 = (val) => {
progressBar1.Value = val;
};
for (int i = 0 ; i < 10 ; i++) {
Thread.Sleep(500);
Dispatcher.BeginInvoke(method2, i * 10);
}
Action method3 = () => {
progressBar1.Visibility = Visibility.Hidden;
};
Dispatcher.BeginInvoke(method3);
};
method.BeginInvoke(null, null);
}
}
}
一个WPF UI只有一个可以用于通信的UI线程——调度线程。只要与UI对象交互的调用是通过UI调度程序完成的,那么所有后台任务都可以在您喜欢的任何线程上完成。通过这个调度程序发送调用是一个常见的任务,因此在每个WPF对象上都提供了dispatcher属性。
我将这样处理这个问题:
private void button2_Click(object sender, RoutedEventArgs e)
{
// Currently running on the WPF thread so the WPF property can be set directly
this.progressBar1.Visibility = System.Windows.Visibility.Visible;
// Create a new thread to do the long running task
Thread worker = new Thread(() =>
{
WebService.DoSomethingThatTakesAges();
// When the above call has completed, update the UI on its dispatcher thread
this.progressBar1.Dispatcher.BeginInvoke(new Action(() =>
{
this.progressBar1.Visibility = System.Windows.Visibility.Hidden;
}));
});
worker.Start();
}
使用System.Threading.Tasks命名空间来创建带有taskscheduler的task可能比直接创建线程更好,但原理是一样的
最后我通过一些技巧实现了这一点。我已经使用委托与DependencyProperty和Dispatacher来更新进度条,任何方式这对我来说都是有效的,经过很长一段时间的各种尝试,见下面我喜欢的代码
private delegate void UpdateProgressBarDelegate(
System.Windows.DependencyProperty dp, Object value);
private void startProgessBar(string controlname)
{
MclarenServerCecksProgressBar.Visibility = Visibility.Visible;
//Stores the value of the ProgressBar
//Create a new instance of our ProgressBar Delegate that points
// to the ProgressBar's SetValue method.
UpdateProgressBarDelegate updatePbDelegate =
new UpdateProgressBarDelegate(MclarenServerCecksProgressBar.SetValue);
bool _status = true;
int flag = 0;
double value = 0;
do
{
/*Update the Value of the ProgressBar: */
Dispatcher.Invoke(updatePbDelegate,
System.Windows.Threading.DispatcherPriority.Background,
new object[] { System.Windows.Controls.ProgressBar.ValueProperty, value });
if (flag == 0)
{
flag == 1
_status = processesServices(controlname);
}
if (_status == false)
{
MclarenServerCecksProgressBar.Visibility = Visibility.Hidden;
}
}
while (_status);
}
它可能是脏的,无论如何修复它,我正在寻找运行进度条,直到我收到一个函数的响应,任何其他建议,以改善这种方式将是非常感谢。