2014-04-19 29 views
0

你好,我有一个与许多后台工作人员的计划。那些后台工作人员只会倾听来自名为“tweet”的变量的变化,然后每个后台创建一个任务来处理每个“tweet”并准备处理另一个Tweet。物业变更通知C#

以下是Tweet类,每1秒钟更新一次或更少。

Tweet tweet = new Tweet(); 
    public class Tweet : INotifyPropertyChanged 
    { 
     private ITweet lastTweet; 

     protected void OnPropertyChanged(PropertyChangedEventArgs e) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) 
       handler(this, e); 
     } 

     protected void OnPropertyChanged(string propertyName) 
     { 
      OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); 
     } 

     public ITweet LastTweet 
     { 
      get { return lastTweet; } 
      set 
      { 
       if (value != lastTweet) 
       { 
        lastTweet = value; 
        OnPropertyChanged("LastTweet"); 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 

现在,在我的BackgroundWorker的DoWork实现:

 Del OnNewTweetEvent = delegate(object sender2, PropertyChangedEventArgs args) 
     { 
      Task task = null; 
      task = new Task(() => 
      { 
       var mytweet = sender2 as Tweet; 
       var tweetText = mytweet.LastTweet.Text; 
       //copy the tweetText in case the mytweet variable changed (not sure) 
       ProcessTweet(tweetText); 
      }); 
      task.Start(); 

     }; 
     this.tweet.PropertyChanged += new PropertyChangedEventHandler(OnNewTweetEvent); 

     //wait and prepare for cancellation 
     var backgroundworker = sender as BackgroundWorker; 
     while (true) 
     { 
      Thread.Sleep(10); 
      if (backgroundworker.CancellationPending) 
      { 
       //remove the notification 
       this.tweet.PropertyChanged -= new PropertyChangedEventHandler(OnNewTweetEvent); 
       return; 
      } 
     } 
    } 

这段代码的逻辑吗?如果tweets每0.01秒钟发送一次tweets,我能够将它们全部获得吗?或者,推特可能会改变,我的后台工作人员没有得到它?

有一个队列或更好的东西? 您的帮助表示赞赏。

回答

0

正如您已经怀疑的那样,您的示例中的方法可能无法捕捉每一条推文或保证每条推文只处理一次。因此,你应该将它们存储在一个集合中。队列将很适合这个目的。

更简单的方法是让一个后台任务监视队列并启动一个处理队列中新推文的异步任务。

但是,有人需要将推文放入队列中(或在您的示例中更新Tweet对象的属性)。所以最简单和最好的方法就是在新的推文到达时启动异步任务。这消除了等待新推文的后台任务,并且消除了系统可能中断的地方。

根据你的代码示例,下面的代码显示了一个简单的方法来处理一个新的推文到达时的权利。您可能希望将代码移动到代码中的另一个位置,并根据需要重命名这些类型。根据您的意见,此示例还针对不同的推文类型采取了不同的操作:

// No need to implement INotifyPropertyChanged as there is no listener anymore 
public class Tweet 
{ 
    private ITweet lastTweet; 

    public ITweet LastTweet 
    { 
     get { return lastTweet; } 
     set 
     { 
      if (value != lastTweet) 
      { 
       lastTweet = value; 
       var actionForTweet = GetActionForTweet(lastTweet); 
       Task task = new Task(() => 
       { 
        actionForTweet(lastTweet); 
       }); 
       task.Start(); 
      } 
     } 
    } 

    private static Action<ITweet> GetActionForTweet(ITweet tweet) 
    { 
     // Decide what to do for which kind of tweet 
     // In the simplest case this is an if/switch statement 
     if (...) 
       return x => { 
           var tweetText = x.Text; 
           ProcessTweet(tweetText); 
          }; 
     else 
       return x => { 
           // Do something else 
          }; 
    } 
} 
+0

感谢您的回复。你能否提供一些代码编辑到我当前的代码中,以最好的方式做到这一点? – circler

+0

@circler:我添加了一个小样本。希望它有帮助。 – Markus

+0

感谢您的代码。做一个集合的最好方法是什么,因为我想在后台工作中运行它,因为每个工作人员都有差异。 – circler