任何有效/可靠的方式来揭露一个事件?

时间:2009-12-10 20:22:37

标签: c# .net events

公开一个事件的任何有效/可靠的方式?

我有一个类MultipleDocumentCopier,它通过SingleDocumentCopier的实例复制多个文档。 SingleDocumentCopier公开了复制文件时触发的事件CopyCompleted

假设我正在复制10个文件,而不是将SingleDocumentCopier.CopyCompleted复制10次, 我想公开一个事件MultipleDocumentCopier.MultipleCopyCompleted

但是,是否有一种标准方法/技术可以组合多个事件并将其触发一次?

我只想提出MultipleDocumentCopier.MultipleCopyCompleted一次 在'MultipleDocumentCopier.singleDocumentCopier_CopyCompleted'中,而不是10次。

以下是示例代码

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace CombineEvents
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var copier = new MultipleDocumentCopier();
            copier.MultipleCopyCompleted += MultipleDocumentCopyCompleted;
            copier.CopyDocuments(new[] {"File1", "File2", "File3"});
        }

        private static void MultipleDocumentCopyCompleted(
            object sender, FileNameEventArgs e)
        {
            Debug.Print("Following documents have been copied");
            foreach (var fileName in e.FileNames)
            {
                Debug.Print("\t\t\"{0}\"", fileName);
            }
        }
    }

    internal class SingleDocumentCopier
    {
        public event EventHandler CopyCompleted;
        protected virtual void OnCopyCompleted()
        {
            if (CopyCompleted != null) CopyCompleted(this, EventArgs.Empty);
        }

        public void Copy(string fileName)
        {
            Debug.Print("Copying = '{0}'", fileName);
            OnCopyCompleted();
        }
    }

    public class MultipleDocumentCopier
    {
        public event EventHandler<FileNameEventArgs> MultipleCopyCompleted;

        protected virtual void OnCopyCompleted(FileNameEventArgs e)
        {
            EventHandler<FileNameEventArgs> completed = MultipleCopyCompleted;
            if (completed != null) completed(this, e);
        }

        public void CopyDocuments(IEnumerable<string> fileNames)
        {
            var copier = new SingleDocumentCopier();
            copier.CopyCompleted += singleDocumentCopier_CopyCompleted;
            foreach (var fileName in fileNames)
            {
                copier.Copy(fileName);
            }
        }

        public static void singleDocumentCopier_CopyCompleted(
            object sender, EventArgs e)
        {
            // I want to raise "MultipleDocumentCopier.MultipleCopyCompleted" when
            // all files, `fileNames` in "CopyDocuments" have been copied,
            // not for every file being copied.
        }
    }

    public class FileNameEventArgs : EventArgs
    {
        private readonly List<string> _FileNames;

        public List<string> FileNames
        {
            get { return _FileNames; }
        }

        public FileNameEventArgs(IEnumerable<string> fileNames)
        {
            _FileNames = fileNames.ToList();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

为什么不从MultipleDocumentCopier.OnCopyCompleted的末尾拨打CopyDocuments,完全忘记singleDocumentCopier_CopyCompleted

或者这可能是伪代码,你真正的代码更复杂?也许您可以在MultipleDocumentCopier中保留一组未完成的文件名,每次引发singleDocumentCopier_CopyCompleted时,都会从集合中删除一个文档。收集变空后,请致电MultipleDocumentCopier.OnCopyCompleted

编辑: Re'有标准方式吗?' - 不是我在C#中意识到的; F#有一组有趣的机制来组合这样的事件,但我认为编程语言的改变不是一种选择。