0

我有下一个界面:

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

我想要 IObservable,它会在 ITask.Update 事件触发时触发 IObserver.OnNext,在 ITask.Completed 事件触发时触发 IObserver.OnCompleted。我可以使用 RX 完成这种组合,否则这是不可能的,我应该为此进行自定义实现。

4

2 回答 2

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"));
于 2013-11-03T15:46:39.383 回答
1

这是一个人为的示例,它显示了在标准 .NET 事件上发布的 5 个“更新”,然后是一个包装标准事件并在“完成”发生时结束的可观察序列。

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");
        }
    }
}
于 2013-11-03T15:52:32.117 回答