单独线程上的进度条未更新
本文关键字:更新 线程 单独 | 更新日期: 2023-09-27 18:22:28
在我的项目中,我有一个Form
,就像任务对话框一样,它显示在自己的线程上。。。这样,当主线程锁定时,任务对话框的ProgressBar
和状态仍然可以更新。问题是ProgressBar
没有更新。状态文本会更新,但ProgressBar
直到Form
关闭之前才移动。Form
正在主线程中打开。这是我的代码:
public partial class TaskForm : Form
{
/// <summary>
/// Gets or Sets whether the task is cancelable
/// </summary>
protected bool Cancelable = true;
/// <summary>
/// Returns whether the Task form is already open and running
/// </summary>
/// <returns></returns>
public static bool IsOpen
{
get { return (Instance != null && !Instance.IsDisposed); }
}
/// <summary>
/// The task dialog's instance
/// </summary>
private static TaskForm Instance;
/// <summary>
/// Private constructor... Use the Show() method rather
/// </summary>
private TaskForm()
{
InitializeComponent();
}
/// <summary>
/// Open and displays the task form.
/// </summary>
/// <param name="Parent">The calling form, so the task form can be centered</param>
public static void Show(Form Parent, string WindowTitle, string InstructionText, string SubMessage, bool Cancelable, ProgressBarStyle Style)
{
// Make sure we dont have an already active form
if (Instance != null && !Instance.IsDisposed)
throw new Exception("Task Form is already being displayed!");
// Create new instance
Instance = new TaskForm();
Instance.Text = WindowTitle;
Instance.labelInstructionText.Text = InstructionText;
Instance.labelContent.Text = SubMessage;
Instance.Cancelable = Cancelable;
Instance.progressBar.Style = Style;
// Hide Cancel
if (!Cancelable)
{
Instance.panelButton.Hide();
Instance.Padding = new Padding(0, 0, 0, 15);
Instance.BackColor = Color.White;
}
// Set window position to center parent
double H = Parent.Location.Y + (Parent.Height / 2) - (Instance.Height / 2);
double W = Parent.Location.X + (Parent.Width / 2) - (Instance.Width / 2);
Instance.Location = new Point((int)Math.Round(W, 0), (int)Math.Round(H, 0));
// Run form in a new thread
Thread thread = new Thread(new ThreadStart(ShowForm));
thread.IsBackground = true;
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
Thread.Sleep(100); // Wait for Run to work
}
/// <summary>
/// Closes the Task dialog
/// </summary>
public static void CloseForm()
{
if (Instance == null || Instance.IsDisposed)
throw new Exception("Invalid Operation. Please use the Show method before calling any operational methods");
Instance.Invoke((Action)delegate()
{
Instance.Close();
});
}
/// <summary>
/// Runs the form in a new application, to prevent thread lock
/// </summary>
protected static void ShowForm()
{
Application.Run(Instance);
}
/// <summary>
/// Updates the instruction text on the task dialog
/// </summary>
/// <param name="Message"></param>
public static void UpdateInstructionText(string Message)
{
if (Instance == null || Instance.IsDisposed)
throw new Exception("Invalid Operation. Please use the Show method before calling any operational methods");
Instance.Invoke((Action)delegate()
{
Instance.labelInstructionText.Text = Message;
});
}
/// <summary>
/// Updates the detail text above the progress bar
/// </summary>
/// <param name="Message"></param>
public static void UpdateStatus(string Message)
{
if (Instance == null || Instance.IsDisposed)
throw new Exception("Invalid Operation. Please use the Show method before calling any operational methods");
Instance.Invoke((Action)delegate()
{
Instance.labelContent.Text = Message;
});
}
/// <summary>
/// Updates the progress bar's value
/// </summary>
/// <param name="Percent"></param>
public static void UpdateProgress(int Percent)
{
if (Instance == null || Instance.IsDisposed)
throw new Exception("Invalid Operation. Please use the Show method before calling any operational methods");
Instance.Invoke((Action)delegate()
{
Instance.progressBar.Step = Percent;
Instance.progressBar.PerformStep();
Instance.progressBar.Refresh();
});
}
#region Non Static
private void CancelBtn_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
#endregion
}
当我调用UpdateStatus
和UpdateInstructionText
方法时,文本更新是没有意义的,但当调用UpdateProgress
时,ProgressBar
不会更新。任何帮助都将不胜感激。
通过查看代码,可以在progressBar.Step
属性中传递UpdateProgress()
方法中的百分比,该步骤指示调用PerformStep()时要增加的量。
由于UpdateProgress()
方法是以百分比为单位使用的,所以我将
Instance.progressBar.Step = Percent;
进入静态Show()方法
...
Instance.progressBar.Style = Style;
Instance.progressBar.Step = Percent;
...
你可以看到它更新进度条的百分比。
我正在使用以下示例
TaskForm.Show(this, "Task is executing...", "Step 1 - Preparing...",
"Runninig", true, ProgressBarStyle.Continuous);
for (int i = 1; i <= 100; i++)
{
TaskForm.UpdateInstructionText("Step 1 - Executing..." + i );
TaskForm.UpdateStatus("Running " + i);
TaskForm.UpdateProgress(i);
Thread.Sleep(1000);
}