【问题标题】:How can I handle an interface method that may or may not be async?如何处理可能是异步的接口方法,也可能不是异步的接口方法?
【发布时间】:2023-04-02 20:37:01
【问题描述】:

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

 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,以便他们可以成为awaited。问题是当我有一个没有任何异步组件的序列化方法时。我可以做以下两件事之一:

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

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

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

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

【问题讨论】:

  • 你可以等待Task.Delay(0),它会立即返回。
  • @HansPassant 我更喜欢那个解决方案^^
  • 你的图片处理是第三方库吗?我问是因为在我看来,图像编码(和一般的序列化)不是自然的async 操作。也就是说,我更喜欢@svick 的解决方案,它类似于选项 B,开销更少。
  • @StephenCleary 不,只是普通的 BitmapEncoder 东西,但是所有将其转换为流和东西的调用都是异步的,我找不到其他方法来替换它们。例如,我在 WinRT 上找不到与 stream.ReadAsync 等效的 Stream.Read,而创建 BitmapEncoder 类的唯一方法是通过其 CreateAsync 方法。

标签: c# asynchronous windows-runtime c#-5.0 async-await


【解决方案1】:

我认为这里最好的解决方案,假设你想同步执行方法是正常写,除非你会在方法结束时返回一个完整的Task

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

如果您想要一个没有值的Task(即实际上只是Task,而不是Task&lt;TResult&gt;),您可以使用例如Task.FromResult(true)(这是一个Task&lt;bool&gt;)并将其隐式转换为@987654330 @。

【讨论】:

  • 在您看来,这与 Task.Delay(0) 的 cmets 中的建议相比如何?
  • @borrrden 实际上,我认为没有区别。从逻辑上讲,我认为FromResult() 更有意义,因为您想要一个完整的Task,而不是延迟。此外,该代码的同步版本是Thread.Sleep(0),它具有特殊含义。这可能会令人困惑。
猜你喜欢
  • 1970-01-01
  • 2012-11-14
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多