首先必须说我是新手开发者。
处理一个C#项目,我希望以单独的形式实现“等待”(throbber)指标。经过大量的研究和反复试验之后,建议的方法是使用与当前表单/线程中的单独线程相加的线程来加载表单。
我使用这种方法的原因是因为最初在throbber表单上使用Show()方法生成了透明表单。我不能使用ShowDialog,因为我需要在显示throbber后运行一些代码,之后完成我想关闭throbber表单。
无论如何..在尝试了许多不同的方法在一个单独的线程中加载throbber表单后,我仍然会遇到一个错误,试图从一个与它创建的线程不同的线程访问它。这是一个kelton版本的应该对我的问题有所了解的项目代码:
我正在为多线程工作的例子是在一个单独的线程中创建自己的spashscreen的流行链接... http://www.codeproject.com/Articles/5454/A-Pretty-Good-Splash-Screen-in-C
public class Main
{
public void CheckData()
{
try
{
ProgressBar pb = new ProgressBar();
pb.ShowProgressBar();
//do data checking here
pb.CloseForm()
}
catch(Exception e)
{
}
}
}
public partial class ProgressBar : Form
{
static Thread ms_oThread = null;
public bool shouldStop = false;
static ProgressBar ms_ProgBar = null;
public ProgressBar()
{
InitializeComponent();
//DoWork();
}
public void ShowForm()
{
ms_ProgBar = new ProgressBar();
Application.Run(ms_ProgBar);
}
public void CloseForm()
{
ms_ProgBar.Close();
}
public void ShowProgressBar()
{
// Make sure it is only launched once.
if (ms_ProgBar != null)
return;
ms_oThread = new Thread(new ThreadStart(ShowForm));
ms_oThread.IsBackground = true;
ms_oThread.SetApartmentState(ApartmentState.STA);
ms_oThread.Start();
while (ms_ProgBar == null || ms_ProgBar.IsHandleCreated == false)
{
System.Threading.Thread.Sleep(1000);
}
}
}
答案 0 :(得分:0)
您正在创建ProgressBar
两次。一旦进入主函数,一次进入新线程。您还从主函数(以及从未显示的窗口)调用CloseWindow方法,而不是在新的线程窗口上调用。
您只想创建ProgressBar
并使用新主题显示它。将您的静态ProgressBar
字段公开,以便您可以直接从Main调用close,但请确保使用Invoke来执行此操作,因为它不在该Window的GUI线程上。
此外,ShowProgressBar应该是静态的。
这是重写尝试:
public class Main
{
public void CheckData()
{
try
{
ProgressBar.ShowProgressBar();
//do data checking here
ProgressBar.CloseForm();
}
catch(Exception e)
{
}
}
}
public partial class ProgressBar : Form
{
static ProgressBar _progressBarInstance;
public ProgressBar()
{
InitializeComponent();
//DoWork();
}
static void ShowForm()
{
_progressBarInstance = new ProgressBar();
Application.Run(ms_ProgressBar);
}
public static void CloseForm()
{
_progressBarInstance.Invoke(new Action(_progressBarInstance.Close));
_progressBarInstance= null;
}
public static void ShowProgressBar()
{
// Make sure it is only launched once.
if (_progressBarInstance != null)
return;
var ms_oThread = new Thread(new ThreadStart(ShowForm));
ms_oThread.IsBackground = true;
ms_oThread.SetApartmentState(ApartmentState.STA);
ms_oThread.Start();
}
}