1

メッセージ キューからメッセージのリストを読み取るメソッドがあります。署名は次のとおりです。

IList<TMsg> Read<TMsg>(MessageQueue queue, int timeout, MessageQueueTransaction tx);

基本的な機能は、指定されたトランザクションを使用して、タイムアウト内にキューからできるだけ多くのメッセージを読み取ることです。私が抱えている問題は、タイムアウトを強制する最善の方法を決定することです。現在、2 つの作業バージョンがあります。これらは:

  • タイムアウトで BeginPeek を使用します。成功した場合、メッセージはトランザクション受信呼び出しで削除されます。BeginPeek のタイムアウトは、読み取りが開始された時間と現在の時間に基づいて、各呼び出しの後に再計算されます。
  • タイムアウト値で Receive を使用し、タイムアウトの期限が切れたときに例外をキャッチします。

最初のアプローチの問題は、キューを DenySharedReceive モードで読み取る必要があることです。そうしないと、メッセージが Peek と Receive の間に存在することを保証できません。2 番目の方法の問題は、例外をスローして処理する必要があることです (ただし、内部的かつ透過的に)。これは、各呼び出しが常に例外で終了するため、例外的な場合にのみ例外をスローするという考えに反するため、おそらく優れた設計ではありません。状況。

これをどのように達成するか、またはこれらの2つの手法と私の懸念についてコメントする他の提案はありますか?

4

2 に答える 2

1

リアクティブな例外を使用してメッセージのプロデューサーを作成し、Observable.Bufferを使用してタイムアウトを管理し、後でこのプロデューサーをサブスクライブできます。

public IEnumerable<Message> GetMessage()
{
    //do the peek and receive a single message
    yield return message;
}

//and then something like
var producer = GetMessage().ToObservable();

// this is where your timeout goes
var bufferedMessages = producer.Buffer(TimeSpan.FromSeconds(3));

var disp = bufferedMessages.Subscribe(messages =>
    {
        Console.WriteLine("You've got {0} new messages", messages.Count());
        foreach (var message in messages)
            Console.WriteLine("> {0}", message); // process messages here
    });

disp.Dispose(); // when you no longer want to subscribe to the messages

より反応的な例については、こちらをご覧ください

于 2012-09-21T21:54:33.970 に答える
0

少し調査した後、少なくとも.NETに関する限り、手斧のコメントは「答え」に最も近いものです。ラップされたネイティブメソッドは、「TIMEOUT」の戻り値(エラー値ではなく)を提供しますが、これは.NETによる例外と見なされ、ネイティブコードを再ラップする価値はありません。私は試した。:p

于 2012-12-28T01:05:03.060 に答える