如何处理可能是或可能不是异步的接口方法?

本文关键字:异步 接口 方法 处理 何处理 | 更新日期: 2023-09-27 18:09:17

我正在尝试创建一个序列化接口(类似于Cocoa的NSCoding协议),这样我就可以获得一个类的快速二进制表示,以便通过网络发送或存储在数据库中。然而,在某些情况下(特别是涉及图像编码的情况下),有许多只使用异步的方法需要await。然而,如果字节没有按顺序写入,那么整个表示当然是损坏的。在继续处理下一个对象之前,必须确保当前对象已经完成序列化。下面是我所做的主循环。

 public async static Task<byte[]> Serialize(this IList<ISerializable> list) {
        using (Archiver archiver = new Archiver()) {
            archiver.Write(list.Count);
            foreach (ISerializable value in list) {
                await archiver.Write(value);
            }
            return archiver.Result;
        }
    }

Archiver只是在底层使用MemoryStreamBitmapWriter来写BinaryWriter可以直接接受的值,或者ISerializable对象,然后将结果作为字节数组输出。ISerializable只是两个方法(SerializeDeserialize)的接口。它们都返回Task,因此它们可以是await。问题是,当我有一个没有任何异步组件的序列化方法时。我可以做两件事中的一件:

A)我可以将async附加到该类的序列化方法上,并忍受编译器警告说它将同步执行(我不喜欢编译器警告)。

B)在方法结束时手动返回一个空任务(return Task.Run(() => {});)。然而,这看起来和闻起来真的很奇怪。

A和B的执行似乎都没有问题,但是这种方法是否存在我可能忽略的问题?我不知道Windows运行时中的二进制序列化器(我包含标记只是为了消除任何混淆)。也许有一个选项C可以让我考虑一下?实际上,我不想让序列化方法异步,但由于某种原因task.Wait()没有等待,我从试图使用CreateAsync创建的对象之前得到一个空引用异常。

EDIT我想到了一个选项c。我可以在await Task.Run(...)调用中包装整个方法。这正常吗?

如何处理可能是或可能不是异步的接口方法?

我认为这里最好的解决方案,假设您想同步执行方法是正常编写它,除了您将在方法结束时返回完整的Task

要获得具有特定值的完整Task,您可以使用Task.FromResult()

如果你想要一个没有值的Task(即实际上只是Task,而不是Task<TResult>),你可以使用例如Task.FromResult(true)(这是一个Task<bool>)并隐式地将其强制转换为Task