我有一个按钮。它会打开一个文件并处理一个文件。我想在处理文件时显示进度条。
当我在做。工作
public MainframeDataExchangeTool()
{
InitializeComponent();
_ProgressBar.Style = ProgressBarStyle.Marquee;
_ProgressBar.Visible = false;
_Random = new Random();
InitializeBackgroundWorker();
}
private void InitializeBackgroundWorker()
{
_BackgroundWorker = new BackgroundWorker();
_BackgroundWorker.WorkerReportsProgress = true;
_BackgroundWorker.DoWork += (sender, e) => ((MethodInvoker)e.Argument).Invoke();
_BackgroundWorker.ProgressChanged += (sender, e) =>
{
_ProgressBar.Style = ProgressBarStyle.Continuous;
_ProgressBar.Value = e.ProgressPercentage;
};
_BackgroundWorker.RunWorkerCompleted += (sender, e) =>
{
if (_ProgressBar.Style == ProgressBarStyle.Marquee)
{
_ProgressBar.Visible = false;
}
};
}
在我的按钮中单击我正在做
private void btnOpenScriptFile_Click(object sender, EventArgs e)
{
try
{
loadScriptFlDlg.Filter = Constants.SCRIPT_FILE_FILTER;
loadScriptFlDlg.FilterIndex = 3;
loadScriptFlDlg.RestoreDirectory = true;
loadScriptFlDlg.FileName = string.Empty;
DialogResult objDialogResult = loadScriptFlDlg.ShowDialog();
if (objDialogResult.Equals(DialogResult.OK))
{
_BackgroundWorker.RunWorkerAsync(new MethodInvoker(() =>
{
_ProgressBar.BeginInvoke(new MethodInvoker(() => _ProgressBar.Visible = true));
for (int i = 0; i < 100; i++)
{
Thread.Sleep(10);
_BackgroundWorker.ReportProgress(i);
}
}));
EnableDisableControls("OpenScript");
string strScriptError = LoadScriptFromFile(loadScriptFlDlg.FileName);///loading will taking time but progress bar not showing
基本上进度条在数据加载结束时显示,但在加载数据时不显示
答案 0 :(得分:1)
您无法看到进度,因为UI线程无法更新UI,因为它正忙于加载您的文件。您必须从后台工作程序调用{{1}}并保持UI线程可以自由处理事件并更新UI。
答案 1 :(得分:0)
感到惊讶的是,编译器并没有因为你需要一个额外的东西而放弃了。
您可以打开4个级别的嵌套,但只能关闭3个。
我修改了您的代码,如下所示:
private void btnOpenScriptFile_Click(object sender, EventArgs e)
{
try
{
if (objDialogResult.Equals(DialogResult.OK))
{
_ProgressBar.Style = ProgressBarStyle.Marquee;
_ProgressBar.BeginInvoke(new MethodInvoker(() => _ProgressBar.Visible = true));
for (int i = 0; i < 100; i++)
{
Thread.Sleep(10);
_ProgressBar.BeginInvoke(new Action(() => _ProgressBar.Value = i));
//Process my file here
}
}
}
Catch
{
}
}
为了便于阅读,我总是建议减少空行数。 我还发现'allman'样式包围是最容易调试的。
但与往常一样,每个人都是他自己的。
编辑:
OP编辑后的代码:
尝试添加:
application.doevents()
之后:
_BackgroundWorker.ReportProgress(i);
为什么呢?代码将保留在for循环中直到完成。通过执行'doevents',你告诉它在下一个循环之前进行外部更新。
如果没有'doevents',我猜你只会看到0和100。
答案 2 :(得分:0)
我在我的项目中用2个方法(例如)
1 * Invoke(new Action(()=&gt; _ProgressBar.Visible = true));
2 *或在Application.DoEvents()
_BackgroundWorker.ReportProgress(i);
答案 3 :(得分:0)
使用BackgroundWorker(bgw)完成类似的操作。
private void MyMethod()
{
bgw.RunWorkerAsync(); //this calls the DoWork event
}
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
//Expensive task
//Calculate how far you through your task (ie has read X of Y bytes of file)
bgw.ReportProgress(myInteger);
}
private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
myProgressBar.Value = e.ProgressPercentage;
}
确保将BackgroundWorker的“WorkerReportsProgress”属性设置为True!