私はクラスのクイックバイナリ表現をネットワーク経由で送信したり、データベースに保存したりできるように、シリアル化インターフェイス(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
だけBinaryWriter
直接受け入れるか、ISerializable
オブジェクトができるいずれかの値を書き込むためにフードの下MemoryStream
とBitmapWriter
を使用し、その後、バイト配列として結果を出してくれる。 ISerializable
は、2つのメソッド(Serialize
とDeserialize
)を持つ単なるインターフェイスです。両方ともTask
を返すので、await
にすることができます。問題は、非同期コンポーネントを持たないシリアライズメソッドがある場合です。
A)とにかく、そのクラスのシリアライゼーションメソッドをタックして、コンパイラの警告を出して、同期的に実行することを警告します(私はコンパイラの警告を受けたくありません)。
B)メソッドの最後に手動で空のタスクを返します(return Task.Run(() => {});
)。しかし、これは本当に奇妙に見えます。
AとBの両方が問題なく実行されているように見えますが、このアプローチには問題がありますか?私はWindowsランタイムでバイナリシリアライザを認識していません(混乱を避けるためにタグを付けました)。おそらく、私が考えることができるオプションCがありますか?実際には、シリアライズメソッドを非同期にしたくないのですが、何らかの理由でtask.Wait()
が待機していなかったので、準備が整う前にヌル参照例外が発生しました。CreateAsync
で作成したオブジェクトを使用しようとしました。
EDIT私はオプションCを考えました。await Task.Run(...)
呼び出しでメソッド全体をラップすることができます。これは正常でしょうか?
タスクを待つことができます。遅延(0)、すぐに戻ります。 –
@HansPassant私はその解決策が好きです^^ – borrrden
画像処理はサードパーティのライブラリですか?イメージエンコーディング(および一般的なシリアライゼーション)は自然に非同期操作ではないように思えるからです。つまり、私は@ svickのソリューションを好んでいます。これは、オプションBのようなオーバーヘッドは少ないです。 –