2013-11-03 51 views
0

我有一個界面:合併兩個事件進入的IObservable

public interface ITask 
{ 
    event EventHandler<EventArgs> Completed; 
    event EventHandler<UpdateEventArgs> Update; 
} 

我想擁有的IObservable,將火IObserver.OnNext時ITask.Update事件觸發和ITask.Completed當IObserver.OnCompleted事件觸發。我可以使用RX完成這種組合嗎?或者是不可能的,我可以爲此定製實現。

+0

'ITask'是一個令人困惑的名字,因爲'System.Threading.Tasks'命名空間。我會親自選擇別的東西...... –

回答

4

艾克這樣的:

/* Assume you have an instance of ITask here */ 
ITask task; 

var updates = Observable.FromEventPattern<UpdateEventArgs>(task, "Update"); 
var completed = Observable.FromEventPattern<EventArgs>(task, "Completed"); 

var desiredStream = updates.TakeUntil(completed); 

/* example usage */ 
desiredStream.Subscribe(Console.WriteLine, 
         () => Console.WriteLine("Done")); 
1

這裏是一個人爲的例子,顯示5「更新」被刊登在你的標準.NET事件,然後將「完成時,它包裝標準的事件,然後結束一個可觀察序列「發生。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Reactive; 
using System.Reactive.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public class UpdateEventArgs : EventArgs 
    { 
     public string Value { get; set; } 
    } 
    public interface ITask 
    { 
     event EventHandler<EventArgs> Completed; 
     event EventHandler<UpdateEventArgs> Update; 
    } 

    public partial class Form1 : Form, ITask 
    { 
     public event EventHandler<EventArgs> Completed; 

     public event EventHandler<UpdateEventArgs> Update; 

     private Timer m_timer = new Timer(); 

     private int m_timercount = 5; 

     public Form1() 
     { 
      InitializeComponent(); 

      var obUpdate = Observable.FromEventPattern<UpdateEventArgs>(this, "Update"); 
      var obCompleted = Observable.FromEventPattern<EventArgs>(this, "Completed"); 

      var obUpdatesUntilCompletedSequence = obUpdate.TakeUntil(obCompleted); 

      obUpdatesUntilCompletedSequence.Subscribe(new Action<EventPattern<UpdateEventArgs>>(UpdateOccurred), new Action(UpdateCompleted)); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      m_timer.Interval = 1000; 
      m_timer.Start(); 
      m_timer.Tick += m_timer_Tick; 
     } 

     void m_timer_Tick(object sender, EventArgs e) 
     { 
      Update(this, new UpdateEventArgs { Value = DateTime.Now.ToString() }); 

      if (--m_timercount == 0) 
      { 
       Completed(this, new EventArgs()); 

       m_timer.Stop(); 
      } 
     } 

     private void UpdateOccurred(EventPattern<UpdateEventArgs> update) 
     { 
      System.Diagnostics.Debug.WriteLine(update.EventArgs.Value); 
     } 

     private void UpdateCompleted() 
     { 
      System.Diagnostics.Debug.WriteLine("No more updated will be received"); 
     } 
    } 
}