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


    客户需求如下:

    • 要求系统能够同时导入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);

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

  • 相关阅读:
    MD5加密 + 盐
    SQLite数据库--C#访问加密的SQLite数据库
    SQLite问题笔记
    微信开发--Two.菜单生成
    NOIP2018游记(更新完毕)
    HNOI2019 游记
    JXOI2017-2018 解题报告
    网络流20+4题解题报告(已更前20题)
    CodeForces528A (STLset)
    CodeForces 140C New Year Snowmen(堆)
  • 原文地址:https://www.cnblogs.com/xiao_p/p/1558306.html
Copyright © 2020-2023  润新知