巧用异步委托解决异步并发问题

客户需求如下:

  • 要求系统能够同时导入ABCD四个文件。
  • 如果某个文件导入的时候出错,显示错误信息,其它文件能够继续导入。
  • 全部导入之后,通知主线程,程序结束。

最终决定采用异步委托解决这个问题。

首先编写一个委托,通过需求可以知道,委托的方法名如下:

///
/// Import Data Delegate
///
///
导入文件路径
public delegate void ImportDataCallBack(string filePath);

编写FileType枚举,用来表示传递的是哪个文件,因为系统只要求录入四中固定的文件,所以采用枚举。

public enum FileType
{
    File_A,
    File_B,
    File_C,
    File_D
}

为了让每个文件导入之后,都可以通知主程序,我们还需要编写一个统一的回调函数。

private void FinishImport(IAsyncResult result)
{
      if (result.IsCompleted)
      {
            switch ((FileType)result.AsyncState)
            {
                  case FileType.File_A:
                        isFinishedFileA = true;
                        break;
                  case FileType.File_B:
                        isFinishedFileB = true;
                        break;
                  case FileType.File_C:
                        isFinishedFileC = true;
                        break;
                  case FileType.File_D:
                        isFinishedFileD = true;
                        break;
                  default:
                        break;
            }
            if (isFinishedFileA && isFinishedFileB && isFinishedFileC && isFinishedFileD)
            {
                  Environment.Exit(0);
            }
      }
}

为了让每个文件导入的过程中,如果出错,都能得到我们想得到的消息,我们这里自定义一个异常。

public class WorkThreadException : ApplicationException
 
{
       
private FileType fileType;
       
public FileType FileType
       
{
             get { return fileType; }
             set { fileType = value; }
       }


 
public WorkThreadException(string message)
 :
base(message)
 
{
 
}


 
public WorkThreadException()
 
{ }

 
public WorkThreadException(FileType fileType, string message)
 :
base(message)
 
{
       
this.fileType = fileType;
 }

 }

剩下的就是几个文件的导入函数了,File A的代码如下,

public void ImportFileA(string filepath)
 
{
       
try
       {
       // to do : import file a here 
       }
       
catch (Exception ex)
       
{
             WorkThreadException e = new WorkThreadException(ex.Message, FileType.File_A);
             throw (e);
       }
 }

其它的类似,就不写了。

当然,如果为了扩展性考虑的话,你可以写一个接口,然后实现该接口。

最后,在客户端delegate的beginInvoke方法调用这几个导入函数就可以了

 ImportDataCallBack fileA = new ImportDataCallBack(ImportFileA);
 fileA.BeginInvoke(
"FileA_Path", FinishImport, FileType.File_A);

 ImportDataCallBack fileB
= new ImportDataCallBack(ImportFileB);
 fileA.BeginInvoke(
"FileB_Path", FinishImport, FileType.File_B);

 ImportDataCallBack fileC
= new ImportDataCallBack(ImportFileC);
 fileA.BeginInvoke(
"FileC_Path", FinishImport, FileType.File_C);

 ImportDataCallBack fileD
= new ImportDataCallBack(ImportFileD);
 fileA.BeginInvoke(
"FileD_Path", FinishImport, FileType.File_D);

总结:感觉异步委托是比线程和线程池等更为轻量级的异步处理方式,简单的调用,方便的回调函数,都可以简化我们的某些异步开发过程。

posted on 2009-09-01 20:35  xiao_p  阅读(2544)  评论(7编辑  收藏

导航