初步实现了2个窗体的连接。写为泛型,方便替换Splash窗体。当前的Splash类没有保证跨线程方法调用的线程安全,需要使用者在Splash窗体的代码中保证线程安全的调用,这也是我正在想办法解决的问题。
放出包含注释的代码供批判
Splash.cs
新建一个主窗体Form1,Splash窗体Form2,在Form2中添加一个Property供Form1修改,如下:
其中使用了一个我自行定义的委托类型,该委托定义如下:
最后在Form1的Load处理方法中写上:
通过睡眠线程来模拟程序的初始化载入。
放出包含注释的代码供批判
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 == null ) return ;
if (_splashForm == null ) return ;
try
{
_splashForm.Invoke( new MethodInvoker(_splashForm.Close));
}
catch (Exception ex) { }
_splashThread = null ;
_splashForm = null ;
}
#endregion
}
/// 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 == null ) return ;
if (_splashForm == null ) return ;
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;
}
{
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();
Splash < Form2 > .SplashForm.Status = str;
System.Threading.Thread.Sleep( 2000 );
Splash < Form2 > .Close();
通过睡眠线程来模拟程序的初始化载入。