zoukankan      html  css  js  c++  java
  • 巧用异步委托解决异步并发问题

    客户需求如下:

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

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

  • 相关阅读:
    C#使用进度条,并用线程模拟真实数据 ProgressBar用法(转)
    装饰者模式(Decorator Pattern)C#版本的
    C# Stream篇(七) -- NetworkStream
    C# Stream篇(六) -- BufferedStream
    C# Stream篇(五) -- MemoryStream
    C# Stream篇(四) -- FileStream
    C# Stream篇(三) -- TextWriter 和 StreamWriter
    C# Stream篇(二) -- TextReader 和StreamReader
    C# Stream篇(—) -- Stream基类
    代理模式(Proxy Pattern)C#版本的
  • 原文地址:https://www.cnblogs.com/xiao_p/p/1558306.html
Copyright © 2011-2022 走看看