0

rxでは次のように書くことができます:

var oe = Observable.FromEventPattern<SqlNotificationEventArgs>(sqlDep, "OnChange");

次に、observableをサブスクライブして、sqlDepオブジェクトのOnChangeイベントをobservableに変換します。

同様に、タスク並列ライブラリを使用してC#イベントからタスクを作成するにはどうすればよいですか?

編集:説明 Drewが指摘し、user375487が明示的に記述したソリューションは、単一のイベントで機能します。タスクが終了するとすぐに...まあそれは終了します。

監視可能なイベントは、いつでも再度トリガーできます。観測可能な流れとして見ることができます。TPLデータフローの一種のISourceBlock。ただし、ドキュメントhttp://msdn.microsoft.com/en-us/library/hh228603(v=vs.110).aspxには、ISourceBlockの例はありません。

私は最終的にそれを行う方法を説明するフォーラムの投稿を見つけました:http ://social.msdn.microsoft.com/Forums/en/tpldataflow/thread/a10c4cb6-868e-41c5-b8cf-d122b514db0e

public static ISourceBlock CreateSourceBlock(Action、Action、Action、ISourceBlock> executor){var bb = new BufferBlock(); executor(t => bb.Post(t)、()=> bb.Complete()、e => bb.Fault(e)、bb); bbを返す; }

//Remark the async delegate which defers the subscription to the hot source.
var sourceBlock = CreateSourceBlock<SomeArgs>(async (post, complete, fault, bb) =>
{
    var eventHandlerToSource = (s,args) => post(args);
    publisher.OnEvent += eventHandlerToSource;
    bb.Complete.ContinueWith(_ => publisher.OnEvent -= eventHandlerToSource);
});

私は上記のコードを試していません。非同期デリゲートとCreateSourceBlockの定義の間に不一致がある可能性があります。

4

2 に答える 2

1

TaskCompletionSource を使用できます。

public static class TaskFromEvent
{
    public static Task<TArgs> Create<TArgs>(object obj, string eventName)
        where TArgs : EventArgs
    {
        var completionSource = new TaskCompletionSource<TArgs>();
        EventHandler<TArgs> handler = null;

        handler = new EventHandler<TArgs>((sender, args) =>
        {
            completionSource.SetResult(args);
            obj.GetType().GetEvent(eventName).RemoveEventHandler(obj, handler);
        });

        obj.GetType().GetEvent(eventName).AddEventHandler(obj, handler);
        return completionSource.Task;
    }
}

使用例:

public class Publisher
{
    public event EventHandler<EventArgs> Event;

    public void FireEvent()
    {
        if (this.Event != null)
            Event(this, new EventArgs());
    }
}

class Program
{
    static void Main(string[] args)
    {
        Publisher publisher = new Publisher();
        var task = TaskFromEvent.Create<EventArgs>(publisher, "Event").ContinueWith(e => Console.WriteLine("The event has fired."));
        publisher.FireEvent();
        Console.ReadKey();
    }
}

編集明確化に基づいて、TPL DataFlow で目標を達成する方法の例を次に示します。

public class EventSource
{
    public static ISourceBlock<TArgs> Create<TArgs>(object obj, string eventName)
        where TArgs : EventArgs
    {
        BufferBlock<TArgs> buffer = new BufferBlock<TArgs>();
        EventHandler<TArgs> handler = null;

        handler = new EventHandler<TArgs>((sender, args) =>
        {
            buffer.Post(args);
        });

        buffer.Completion.ContinueWith(c =>
            {
                Console.WriteLine("Unsubscribed from event");
                obj.GetType().GetEvent(eventName).RemoveEventHandler(obj, handler);
            });

        obj.GetType().GetEvent(eventName).AddEventHandler(obj, handler);
        return buffer;
    }
}

public class Publisher
{
    public event EventHandler<EventArgs> Event;

    public void FireEvent()
    {
        if (this.Event != null)
            Event(this, new EventArgs());
    }
}

class Program
{
    static void Main(string[] args)
    {
        var publisher = new Publisher();
        var source = EventSource.Create<EventArgs>(publisher, "Event");
        source.LinkTo(new ActionBlock<EventArgs>(e => Console.WriteLine("New event!")));
        Console.WriteLine("Type 'q' to exit");
        char key = (char)0;
        while (true)
        {
            key = Console.ReadKey().KeyChar;             
            Console.WriteLine();
            if (key == 'q') break;
            publisher.FireEvent();
        }

        source.Complete();
        Console.ReadKey();
    }
}
于 2012-02-24T17:03:31.670 に答える
1

TPL に組み込まれたイベント非同期パターン (EAP) に直接相当するものはありません。あなたがする必要があるTaskCompletionSource<T>のは、イベントハンドラーで自分自身に通知する を使用することです。WebClient::DownloadStringAsync を使用してパターンを示す例については、MSDN のこのセクションを参照してください。

于 2012-02-24T16:55:53.003 に答える