C#mutithreaded throbber形式

时间:2014-05-08 15:55:05

标签: c# multithreading

首先必须说我是新手开发者。

处理一个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);
        }
    }
}

1 个答案:

答案 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();
    }
}