线程,进度条操作方法 [英] Thread, progressbar howto
问题描述
我正在使用 XslCompiledTransform
将 XML 文件转换为 HTML.XML文件没有那么短,所以转换浪费了很多时间.
I'm using XslCompiledTransform
to transform XML file to HTML.
XML file is not so short, so transformation is waste a lot of time.
我的代码:
xslTransform.Transform(fi.FullName, TMP_TRANSFORMED_XML_PATH);
webBrowser1.Navigate(TMP_TRANSFORMED_XML_PATH);
所以我想使用未绑定到表单的进度条或(更好的)进度图标(对话框?).
So I want to use progress-bar or (better) progress icon (dialog?) which is not bound to a form.
问题是我有两种形式.The 1st one has a list of items and a button, when item selected and button is pressed, 2nd form is shown (not modal), XML file transforms and it's shown in WebBrowser control.
The problem is that I have two forms. The 1st one has a list of items and a button, when item selected and button is pressed, 2nd form is shown (not modal), XML file transforms and it's shown in WebBrowser control.
在第二种形式的构造函数中,我调用 XslCompiledTransform.Load
,初始化控件,然后调用 XslCompiledTransform.Transform()
.
In 2nd form constructor I call XslCompiledTransform.Load
, initialize controls and then call XslCompiledTransform.Transform()
.
在第二个表单中,我也有按钮可以在第一个表单列表项之间导航.因此,当我按>"时,会选择第一个表单中的下一个元素,并重新加载第二个表单的元素 - 例如更改了一些文本,并为新的 XML 文件再次调用 XslCompiledTransform.Transform().
In a second form I also have buttons to navigate between 1st form list items. So when I press '>' then the next element from 1st form is selected, and 2nd form's elements are reloaded - e.g. some text changed and XslCompiledTransform.Transform() is called again for a new XML file.
那么,如何在每次加载第二个表单时组织进度条?
来自第一种形式:
private void OpenSecondForm()
{
if (formTwo == null)
{
formTwo = new FormTwo(this, culture, params);
formTwo .Show();
}
else
{
if (formTwo .IsDisposed)
{
formTwo = new FormTwo(this, culture, params);
formTwo .Show();
}
else
{
formTwo .Reinitialaze(culture, invoice);
}
formTwo .BringToFront();
}
}
public void SelectRow(int moveTo)
{
try
{
/*navigate on list here */
/* ... */
OpenSecondForm();
}
catch (Exception e)
{ MessageBox.Show(e.Message, "ERROR"); }
}
第二种形式:
public FormTwo(Form parent, CultureInfo cultr, string params)
{
culture = cultr;
parentForm = parent;
rm = new ResourceManager("MyProject.Resource", typeof(FormOne).Assembly);
InitializeComponent();
xslTransform = new XslCompiledTransform();
xslTransform.Load(XSL_TRANSFORM_SCHEMA_NAME);
ReInitialazeAll();
}
internal void Reinitialaze(CultureInfo cultr, string params)
{
culture = cultr;
ReInitialazeAll();
}
private void ReInitialazeAll()
{
SelectDatabaseData();
InitCaptions();
InitForms();
}
private void InitForms()
{
EnableDisableButtons();
webBrowser1.DocumentText = "<HTML><BODY></BODY></HTML>";
FillXmlData();
}
private void FillXmlData()
{
xslTransform.Transform(fi.FullName, TMP_TRANSFORMED_XML_PATH);
webBrowser1.Navigate(TMP_TRANSFORMED_XML_PATH);
}
我尝试创建一个线程来执行这些 FillXmlData.但是我的表单在 xml 转换时仍然无法访问.
I've tried to create a thread to execute these FillXmlData. But my forms is still not accessible while xml is transforming.
推荐答案
您需要在单独的线程上运行 XML 转换(以及任何其他冗长的非 UI 加载操作).像这样:
You need to run the XML transformation (and any other lengthy non-UI loading operations) on a separate thread. Something like this:
public FormTwo(Form parent, CultureInfo cultr, string params)
{
culture = cultr;
parentForm = parent;
rm = new ResourceManager("MyProject.Resource", typeof(FormOne).Assembly);
InitializeComponent();
// Show the progress bar
this.ProgressBar.Visible = true;
// Load on another thread
Thread loadingThread = new Thread(new ThreadStart(TransformXml));
loadingThread.Start();
}
private void TransformXml()
{
xslTransform = new XslCompiledTransform();
xslTransform.Load(XSL_TRANSFORM_SCHEMA_NAME);
ReInitialazeAll();
}
注意:这里假设您的进度条名为 ProgressBar
.
Note: This assumes your progress bar is named ProgressBar
.
但是,您需要注意您无法访问另一个线程上的 UI 元素,因此需要在 UI 线程上调用对 ReInitialazeAll()
(其中包含一个错字)的调用.这可以通过执行以下操作安全地完成:
However, you need to be aware that you cannot access UI elements on another thread, so the call to ReInitialazeAll()
(which contains a typo) needs to be invoked on the UI thread. This can be accomplished safely by doing something like:
private void ReInitialazeAll()
{
// Make sure we're running on the UI thread
if (this.InvokeRequired)
{
BeginInvoke(new Action(ReInitialazeAll));
return;
}
// Hide the progress bar
this.ProgressBar.Visible = false;
// ... execute UI-related code
}
这应该会给你一个足够好的开始,你可以从中工作.
This should give you a decent enough start that you can work from.
这篇关于线程,进度条操作方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!