在我們的程序中,很多時候會有一些耗時較長的運算,我們為了保證用戶體驗,讓用戶界面能得到及時的響應。我們一般會采用多線程操作,讓耗時操作在
後台完成,比如我們在上傳文件或其他一些需求要在界面顯示進度條的例子。在 .NET2.0中為我們供了一個BackGroundWorker類可以完成類似的需求,具體
使用我們可以參考MSDN。本文要說的我們自己來完成這樣一個功能,並封裝在通用的基類當中。
1.我們封裝的基類如下:
public abstract class MyAsyncBaseClass
{
//封裝業務方法參數
private class MyMethodParameters
{
public string StringParameter { get; set; }
public int IntParameter { get; set; }
public object CallerStateObject { get; set; }
public System.Windows.Threading.Dispatcher CallingDispatcher { get; set; }
}
//當線程執行完成後被激發的事件
public event EventHandler<MyAsyncEventArgs> MyMethodComplete;
protected void FireMyMethodCompleteEvent(int result, object state)
{
if (MyMethodComplete != null)
{
MyMethodComplete(this, new MyAsyncEventArgs(result, state));
}
}
//業務邏輯程序
public abstract int MyMethod(string stringParameter, int intParameter);
// 異步調用的方法
public void MyMethodAsync(string stringParameer, int intParameter, object state)
{
//Instantiate the parameter wrapper.
MyMethodParameters parameters = new MyMethodParameters()
{
StringParameter = stringParameer,
IntParameter = intParameter,
CallerStateObject = state,
CallingDispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher
};
//創建線程
System.Threading.ThreadPool.QueueUserWorkItem(MyMethodThreaded, parameters);
}
// 線程入口點
private void MyMethodThreaded(object p)
{
MyMethodParameters parameters = (MyMethodParameters)p;
//調用實際的MyMethod方法
int result = MyMethod(parameters.StringParameter, parameters.IntParameter);
///Incorect way to raise event
///This would cause a "Cross-thread operation not valid Exception"
///FireMyMethodCompleteEvent(result, parameters.CallerStateObject);
///
///Correct way to raise event
///Construct a new delegate with the signature <int, object> and register
///it on the callers event queue.
parameters.CallingDispatcher.BeginInvoke(
new Action<int, object>(FireMyMethodCompleteEvent),
result,
parameters.CallerStateObject
);
}
}
2.事件參數如下:
public class MyAsyncEventArgs : EventArgs
{
/// 用戶狀態對象
public object State { get; protected set; }
/// 線程操作完的結果
/// </summary>
public int IntResult { get; protected set; }
public MyAsyncEventArgs(int result, object state)
{
State = state;
IntResult = result;
}
}
3.我們具體要實現的類如下:
public class MyClass : MyAsyncBaseClass
{
public override int MyMethod(string stringParameter, int intParameter)
{
System.Threading.Thread.Sleep(2000);
MessageBox.Show("業務邏輯程序執行的地方");
return 42;
}
}
4.下面我來做下測試,如下:

public partial class Form1 : Form
{
protected MyAsyncBaseClass class1;
public Form1()
{
InitializeComponent();
class1 = new MyClass();