通过属性更改C#通知多个后台工作者

时间:2014-03-06 08:29:24

标签: c# .net events event-handling backgroundworker

我有一个名为的全局变量: string tweet;

我运行了几个后台工作程序,它只会等待tweet变量的值更改。然后运行一个名为ProcessTweet( object sender, MyCustomEventArgs args )

的函数

我的问题是从所有后台工作者处理属性更改事件的最佳方法是什么,然后根据推文值和传递给ProcessTweet函数的另一个参数处理结果。

我试着看一下INotifyPropertyChanged,但我不确定如何处理来自每个后台工作者的OnValueChange事件。它会运行相同的ProcessTweet函数一次,还是每个后台工作程序都会运行该函数的实例?

编辑:

private ITweet _LastTweet;
public ITweet LastTweet
{
   get { return this._LastTweet; }
   set
   {
      this._LastTweet = value;     
    }
}

仍然不确定如何以最佳方式处理属性更改事件^

以下是代码的其余部分

    private void bgworker_DoWork(object sender, DoWorkEventArgs e)
    {
        MyCustomClass myCustomClass = e.Argument as MyCustomClass;
        //here I want to listen on the LastTweet Value Change event and handle it
    }

    List<BackgroundWorker> listOfBGWorkers = new List<BackgroundWorker>();
    private BackgroundWorker CreateBackgroundWorker()
    {
        BackgroundWorker bgworker = new BackgroundWorker();
        //add the DoWork etc..
        bgworker.DoWork += new System.ComponentModel.DoWorkEventHandler(bgworker_DoWork);

        return bgworker;
    }

    private void buttonStart_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < 10; i++)
        {
            //Create the background workers
            var bgworker = CreateBackgroundWorker();
            listOfBGWorkers.Add(bgworker);
            //get the MYCustomClass value;
            var myCustomClass = SomeFunction();
            bgworker.RunWorkerAsync(myCustomClass);

        }


    }

1 个答案:

答案 0 :(得分:1)

好的 - 这是一个小型控制台应用程序,用于演示我想想您正在尝试做什么。

  1. 它在一个帖子中创建了一个“推文来源”。
  2. 您可以订阅此“来源”,并在新推文“到达”时收到通知。
  3. 您创建TweetHandlers,其中包含要处理的推文的内部队列
  4. 您将这些TweetHandler订阅到源
  5. 当新推文到达时,会通过活动订阅将其添加到所有 TweetHandlers的队列中
  6. TweetHandlers设置为在自己的任务中运行。每个TweetHandler都有自己的委托,用于在推文上执行可自定义的操作。
  7. 代码如下:

    interface ITweet
    {
        object someData { get; }
    }
    
    class Tweet : ITweet
    {
        public object someData { get; set; }
    }
    
    class TweetSource
    {
        public event Action<ITweet> NewTweetEvent = delegate { };
    
        private Task tweetSourceTask;
    
        public void Start()
        {
            tweetSourceTask = new TaskFactory().StartNew(createTweetsForever);
        }
    
        private void createTweetsForever()
        {
            while (true)
            {
                Thread.Sleep(1000);
                var tweet = new Tweet{ someData = Guid.NewGuid().ToString() };
                NewTweetEvent(tweet);
            }
        }
    }
    
    class TweetHandler
    {
        public TweetHandler(Action<ITweet> handleTweet)
        {
            HandleTweet = handleTweet;
        }
    
        public void AddTweetToQueue(ITweet tweet)
        {
            queueOfTweets.Add(tweet);
        }
    
        public void HandleTweets(CancellationToken token)
        {
            ITweet item;
            while (queueOfTweets.TryTake(out item, -1, token))
            {
                HandleTweet(item);
            }
        }
    
        private BlockingCollection<ITweet> queueOfTweets = new BlockingCollection<ITweet>();
        private Action<ITweet> HandleTweet;
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var handler1 = new TweetHandler(TweetHandleMethod1);
            var handler2 = new TweetHandler(TweetHandleMethod2);
    
            var source = new TweetSource();
            source.NewTweetEvent += handler1.AddTweetToQueue;
            source.NewTweetEvent += handler2.AddTweetToQueue;
    
            // start up the task threads (2 of them)!
            var tokenSource = new CancellationTokenSource();
            var token = tokenSource.Token;
            var taskFactory = new TaskFactory(token);
            var task1 = taskFactory.StartNew(() => handler1.HandleTweets(token));
            var task2 = taskFactory.StartNew(() => handler2.HandleTweets(token));
    
            // fire up the source
            source.Start();
    
            Thread.Sleep(10000);
            tokenSource.Cancel();
        }
    
        static void TweetHandleMethod1(ITweet tweet)
        {
            Console.WriteLine("Did action 1 on tweet {0}", tweet.someData);
        }
    
        static void TweetHandleMethod2(ITweet tweet)
        {
            Console.WriteLine("Did action 2 on tweet {0}", tweet.someData);
        }
    }
    

    输出如下:

    Did action 2 on tweet 892dd6c1-392c-4dad-8708-ca8c6e180907
    Did action 1 on tweet 892dd6c1-392c-4dad-8708-ca8c6e180907
    Did action 2 on tweet 8bf97417-5511-4301-86db-3ff561d53f49
    Did action 1 on tweet 8bf97417-5511-4301-86db-3ff561d53f49
    Did action 2 on tweet 9c902b1f-cfab-4839-8bb0-cc21dfa301d5