IObservable.GetAwaiter的错误处理
本文关键字:处理 错误 GetAwaiter IObservable | 更新日期: 2023-09-27 17:51:09
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) )
;
我试着看可用的文档,但不能走远。我是新的结合异步/任务与IObservable,所以我有一个概念上的错误,请让我知道。
处理异常的一种可能方法是使用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
}
}
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之间的封闭也可以工作。