从事件委托创建一个Observable

时间:2018-08-22 13:37:27

标签: c# observable system.reactive

我必须以这种方式映射通过本机驱动程序完成的设备硬件输入:

FontWeight

StaticResource在输入来自硬件时被调用,并以这种方式定义来调用我的OnCallback方法:

GIS_LF_API.TSLF_SetReaderMode(handle, 1);
GIS_LF_API.TSLF_StartAutoRead(handle, '\r', AutoReadProc);

AutoReadProc在驱动程序中的定义如下:

private GIS_LF_API.AutoReadCallback AutoReadProc = OnCallback;
private static int OnCallback(string Arr, int Len)
{
    //do somethings
    return intValue;
}

现在我想在调用事件时映射一个AutoReadCallback。 怎么办?我尝试使用public delegate int AutoReadCallback([MarshalAsAttribute(UnmanagedType.LPStr)] string pData, int Len); ,但找不到映射它的方法。

2 个答案:

答案 0 :(得分:0)

您可以在Event周围粘贴一个事件,然后使用Observable.FromEvent(可能是首选),或在您的处理程序中粘贴Subject,然后将该对象暴露为可观察的对象。

事件解决方案:

public class X
{
    public X()
    {
        AutoReadProc += OnCallback; //If still necessary.
        IntObservable = Observable.FromEvent<GIS_LF_API.AutoReadCallback, int>(h => AutoReadProc += h, h => AutoReadProc -= h);
    }

    public event GIS_LF_API.AutoReadCallback AutoReadProc;
    private int OnCallback(string Arr, int Len)
    {
        //do something, if necessary. Not required for observable.
        var intValue = 0;
        return intValue;
    }
    public IObservable<int> IntObservable { get; }

}

主题解决方案:

public class Y
{
    private readonly Subject<int> _subject = new Subject<int>();
    public Y()
    {
        IntObservable = _subject.AsObservable();
    }

    private int OnCallback(string Arr, int Len)
    {
        //do something
        var intValue = 0;
        _subject.OnNext(intValue);
        return intValue;
    }
    public IObservable<int> IntObservable { get; } 

}

我将OnCallback设为非静态,这与您的解决方案不同。如果是静态的,它仍然可以工作,但是Subject也必须是静态的。

答案 1 :(得分:0)

可以尝试一下:

void Main()
{
    var foo = new Foo();

    Observable
        .FromEvent<AutoReadCallback, int>(a => (pd, l) =>
        {
            var r = pd.Length + l;
            a(r);
            return r;
        }, h => foo.AutoReadCallback += h, h => foo.AutoReadCallback -= h)
        .Subscribe(x => Console.WriteLine(x));

    foo.OnAutoReadCallback("Bar", 2);
}

public delegate int AutoReadCallback(string pData, int Len);

public class Foo
{
    public event AutoReadCallback AutoReadCallback;

    public int OnAutoReadCallback(string pData, int len)
    {
        var arc = this.AutoReadCallback;
        if (arc != null)
        {
            return arc(pData, len);
        }
        return -1;
    }
}

奇怪的是,事件处理程序返回了一个值,因此该代码具有一些多余的外观代码。