2013-04-16 23 views
7

Tôi đang cố gắng tạo một giao diện tuần tự hóa (tương tự như giao thức NSCoding của Cocoa) để tôi có thể nhận được biểu diễn nhị phân nhanh của một lớp để gửi qua mạng hoặc lưu trữ trong cơ sở dữ liệu. Tuy nhiên, một số trường hợp (đặc biệt là liên quan đến mã hóa hình ảnh) có nhiều phương pháp không đồng bộ chỉ yêu cầu await ing. Tuy nhiên, nếu các byte không được viết theo thứ tự thì dĩ nhiên toàn bộ biểu diễn bị hỏng. Tôi phải chắc chắn rằng đối tượng hiện tại được hoàn thành serializing trước khi tôi tiếp tục đối tượng tiếp theo. Đây là vòng lặp chính của những gì tôi đang làm.Làm cách nào tôi có thể xử lý một phương thức giao diện có thể hoặc không thể không đồng bộ?

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 chỉ sử dụng MemoryStreamBitmapWriter dưới mui xe để viết một trong hai giá trị đó BinaryWriter thể chấp nhận trực tiếp, hoặc ISerializable đối tượng, và sau đó khạc nhổ ra kết quả như một mảng byte. ISerializable chỉ là một giao diện với hai phương thức (SerializeDeserialize). Cả hai đều trả về Task để chúng có thể là await ed. Vấn đề là khi tôi có một phương thức serialization không có bất kỳ thành phần async nào. Tôi có thể thực hiện một trong hai điều sau:

A) Tôi có thể tống theo async vào các phương thức tuần tự của lớp đó và đưa ra cảnh báo trình biên dịch nói rằng nó sẽ thực thi đồng bộ (tôi không muốn có cảnh báo trình biên dịch).

B) Trả lại tác vụ trống theo cách thủ công ở cuối phương thức (return Task.Run(() => {});). Tuy nhiên, điều này có vẻ và mùi thực sự kỳ lạ.

Cả A và B dường như thực thi mà không có sự cố, nhưng có bất kỳ vấn đề nào với phương pháp này mà tôi có thể đã bỏ lỡ không? Tôi không nhận thức được một serializer nhị phân trong Windows Runtime (Tôi đã bao gồm thẻ chỉ để xua tan bất kỳ sự nhầm lẫn nào). Có lẽ có một lựa chọn C mà tôi có thể xem xét? Trên thực tế tôi không muốn làm cho các phương thức tuần tự hóa không đồng bộ, nhưng vì lý do nào đó, task.Wait() không chờ đợi, và tôi đã nhận được một ngoại lệ tham chiếu null từ việc cố gắng sử dụng một đối tượng được tạo ra với CreateAsync trước khi nó sẵn sàng.

EDIT Tôi đã nghĩ về tùy chọn C. Tôi chỉ có thể bọc toàn bộ phương thức trong cuộc gọi await Task.Run(...). Điều này có bình thường không?

+0

Bạn có thể đợi Task.Delay (0), nó sẽ trả về ngay lập tức. –

+0

@HansPassant Tôi thích giải pháp đó ^^ – borrrden

+0

Hình ảnh của bạn có đang xử lý thư viện của bên thứ ba không? Tôi hỏi vì có vẻ như với tôi rằng mã hóa hình ảnh (và tuần tự hóa nói chung) không phải là các hoạt động 'async' tự nhiên. Điều đó nói rằng, tôi thích giải pháp @ svick, giống như tùy chọn B với chi phí thấp hơn. –

Trả lời

4

Tôi nghĩ giải pháp tốt nhất ở đây, giả sử bạn muốn thực thi phương thức đồng bộ là viết nó bình thường, ngoại trừ bạn sẽ trả về Task hoàn thành ở cuối phương thức.

Để hoàn thành Task với một số giá trị cụ thể, bạn có thể sử dụng Task.FromResult().

Nếu bạn muốn có một Task không có giá trị (ví dụ: thực sự chỉ Task, không Task<TResult>), bạn có thể sử dụng ví dụ Task.FromResult(true) (mà là một Task<bool>) và ngầm đúc nó vào Task.

+0

Làm thế nào điều này so sánh, trong tâm trí của bạn, để gợi ý trong các ý kiến ​​của 'Task.Delay (0)'? – borrrden

+0

@borrrden Thực tế, tôi không nghĩ có sự khác biệt. Về mặt logic, tôi nghĩ 'FromResult()' có ý nghĩa tốt hơn, bởi vì bạn muốn hoàn thành 'Task', không phải là một sự trì hoãn. Ngoài ra, phiên bản đồng bộ của mã đó là 'Thread.Sleep (0)', có một ý nghĩa đặc biệt. Điều đó có thể gây nhầm lẫn. – svick

Các vấn đề liên quan