一个连接主窗体与Splash窗体的Splash类

来源:互联网 发布:佐菲奥特曼act淘宝 编辑:程序博客网 时间:2024/05/17 20:23
初步实现了2个窗体的连接。写为泛型,方便替换Splash窗体。当前的Splash类没有保证跨线程方法调用的线程安全,需要使用者在Splash窗体的代码中保证线程安全的调用,这也是我正在想办法解决的问题。

放出包含注释的代码供批判

Splash.cs

/// <summary>
/// A bridge class that connect a main form with a splash form
/// </summary>
/// <typeparam name="TForm">Type of the splash form</typeparam>
/// <example>
/// In the entry method of the application:
/// <code>
///     Splash<<c>SplashForm</c>>.Show();
///     MainForm form = new MainForm();
///     Application.Run(form);
/// </code>
/// And terminate the splash form in the code of the main form:
/// <code>
///     Splash<<c>SplashForm</c>>.Close();
/// </code>
/// </example>
/// <remarks>TO-DO: Ensure thread-safety of cross-thread calls in this
class</remarks>
public class Splash<TForm> where TForm : Form, new()
{
    
#region Fields

    
/// <summary>
    
/// The splash form
    
/// </summary>
    private static TForm _splashForm = null;

    
/// <summary>
    
/// The splash working thread
    
/// </summary>
    private static Thread _splashThread = null;

    
#endregion

    
#region Properties

    
/// <value>
    
/// Get the reference of the splash form
    
/// </value>
    
/// <remarks>Programmers must warrant the thread-safety of cross-thread calls</remarks>
    
public static TForm SplashForm
    {
        
get { return _splashForm; }
    }

    
#endregion

    
#region Public Methods

    
/// <summary>
    
/// Show the splash
    
/// </summary>
    public static void Show()
    {
        
if (_splashThread != null)
            
return;

        _splashThread 
= new Thread(
            
new ThreadStart(() =>
            {
                _splashForm 
= new TForm();
                Application.Run(_splashForm);
            }));

        _splashThread.IsBackground 
= true;
        _splashThread.SetApartmentState(ApartmentState.STA);
        _splashThread.Start();
    }

    
/// <summary>
    
/// Close the splash form
    
/// </summary>
    
/// <remarks>This method is called from the main form</remarks>
    public static void Close()
    {
        
if (_splashThread == nullreturn;
        
if (_splashForm == nullreturn;

        
try
        {
            _splashForm.Invoke(
new MethodInvoker(_splashForm.Close));
        }
        
catch (Exception ex) { }

        _splashThread 
= null;
        _splashForm 
= null;
    }

    
#endregion
}


新建一个主窗体Form1,Splash窗体Form2,在Form2中添加一个Property供Form1修改,如下:

    public string Status
    {
        
set
        {
            ChangeStatus(value);
        }
    }

    
public void ChangeStatus(string status)
    {
        
if (this.InvokeRequired)
            
this.Invoke(new Kwan.Delegates.Action<string>(this.ChangeStatus)
                                ,
new object[] { status });
        
else
            
this.Text = status;
    }


其中使用了一个我自行定义的委托类型,该委托定义如下:

    public delegate void Action<T>(T val);


最后在Form1的Load处理方法中写上:

    string str = "Loading";
    Splash
<Form2>.SplashForm.Status = str;
    System.Threading.Thread.Sleep(
2000);
    Splash
<Form2>.Close();


通过睡眠线程来模拟程序的初始化载入。
原创粉丝点击