0
async Task<packet> getMyPacket()
 {   
    IObservable<packet> packets = ...;
        await packets
                 .Where(x => x.frameType == CMD_ID_0 )
                 .FirstAsync()
                 .GetAwaiter()
                 ;

  }

上記のコードスニペットは正常に機能します。

ただし、GetAwaiterでエラー処理はどのように行われますか?

たとえば、タイムアウト時に標準エラーパケットを返す必要がある場合。

await packets
         .Where(x => x.frameType == CMD_ID_0 )
         .FirstAsync()
         .TimeOut( TimeSpan.FromSeconds(5))
         .GetAwaiter (   , ,OnError: return newErrorPacket(TIMEOUT) ) 
         ;

入手可能なドキュメントを調べてみましたが、うまくいきませんでした。async / TasksとIObservableを組み合わせるのは初めてなので、概念上のエラーがあります。お知らせください。

4

2 に答える 2

1

例外を処理するための可能な方法ContinueWithは、次のコードサンプルのようにメソッドを使用することです(コードを機能させるためだけに使用したダミーのクラスと列挙型がいくつかあります。それらを既存のクラスと列挙型に置き換えることができます)。

using System;
using System.Collections.Generic;
using System.Collections;

using System.Reactive.Threading;
using System.Reactive.Linq;
using System.Threading.Tasks;

class Program
{
    public static void Main()
    {
        var packets = getMyPacket().ContinueWith((a) =>
        {
            Packet packet = null;
            if (a.Exception != null && a.Exception.InnerException.GetType() == typeof(TimeoutException))
            {
                packet = new ErrorPacket(Error.TIMEOUT);
            }
            else
            {
                packet = a.Result;
            }
            return packet;
        });

        Console.ReadLine();
        Console.WriteLine(packets.Result.GetType());
    }

    static async Task<Packet> getMyPacket()
    {
        var list = new List<Packet>();
        list.Add(new Packet(FrameType.CMD_ID_0));

        IObservable<Packet> packets = list.ToObservable();
        var aw = await packets
                 .Where(x => x.FrameType == FrameType.CMD_ID_0)
                 .FirstAsync()
                 //.Timeout(TimeSpan.FromSeconds(0))
                 .GetAwaiter();

        return aw;

    }
    class Packet
    {
        public FrameType FrameType { get; set; }
        public Packet() 
        {
        }
        public Packet(FrameType frameType)
        {
            FrameType = frameType;
        }
    }
    class ErrorPacket : Packet
    {
        public ErrorPacket(Error error)
        {
        }
    }

    enum FrameType
    {
        CMD_ID_0,
        CMD_ID_1
    }

    enum Error
    {
        TIMEOUT
    }
}
于 2013-01-10T12:19:56.727 に答える
0

IObservableには、ジョブを実行する「Catch」拡張メソッドがあります。

await packets
         .Where(x => x.frameType == CMD_ID_0 )       
         .TimeOut( TimeSpan.FromSeconds(5))
         .Catch( Observable.Empty<packet>())
         .LastOrDefaultAsync();

上記は、適切な応答パケットを待つか、タイムアウトします。awaitは、空のシーケンスで例外をスローするGetAwaiterを使用するため、LastOrDefaultAsync()はそれを回避するのに役立ちます。または、try-catchで囲むこともできます。

于 2013-02-22T09:53:04.070 に答える