2013-07-31 30 views
5

Tôi đã học được các thuộc tính tải lười trong kho lưu trữ của mình. Bây giờ tôi muốn làm điều đó, nhưng tôi cũng cần phải tải một cái gì đó từ một trang web (sử dụng Httpclient) có nghĩa là tài sản của tôi sẽ không đồng bộ.Thuộc tính tải kém với Async

public async Task<List<NewsModel>> News 
{ 
    get 
    { 
     if (_news == null) 
     { 
      CacheProvider cache = new CacheProvider(); 
      object cachedNews = cache.Get("news"); 

      if (cachedNews == null) 
      { 
       var client = new HttpClient(); 
       // await HttpResponse 
      } 

     } 
     return _news; 
    } 

    set 
    { 
     _news = value; 
    } 
} 

Tuy nhiên, visual studio được nói với tôi rằng

"The async modifier là không hợp lệ cho mặt hàng này"

đồng thời nêu bật từ "Tin tức" trong lần đầu tiên hàng.

Có thể thực hiện việc này không? Hay tôi phải viết một phương pháp riêng biệt?

+0

Tôi mang nó rằng bạn đã có báo cáo kết quả sử dụng cho System.Threading.Tasks? Ngoài ra, khung công tác .NET nào là nhắm mục tiêu này? Có phải Silverlight không? - Đừng bận tâm, chỉ thấy rằng đây là tài sản. Bạn sẽ muốn chuyển đổi thành các phương thức. –

+0

Dường như với tôi như thuộc tính 'Tin tức' sẽ trực giác có kiểu' List ', trang trí' Task <> 'dường như không tự nhiên ở đây. Tại sao bạn cảm thấy rằng bạn cần phơi bày bản chất 'Task <>'? –

+0

@AndrewCoonce Trên thực tế, nếu anh ấy muốn viết một phương thức * không đồng bộ *, anh ấy chắc chắn sẽ phải viết nó như là trả lại một nhiệm vụ. –

Trả lời

5

Trước hết, các thuộc tính có tác dụng phụ thường không tốt.

Trong trường hợp này, chỉ cần đọc thuộc tính này sẽ khởi chạy một chuỗi, một số lưu lượng mạng và một số xử lý trên máy chủ từ xa.

Đây phải là phương pháp chứ không phải thuộc tính.

Thứ hai, trình biên dịch là đúng, thuộc tính không được phép không đồng bộ. Bây giờ, bạn có thể chắc chắn viết thuộc tính trả về tác vụ không đồng bộ, nhưng bạn không được phép sử dụng từ khóa async. Về cơ bản chỉ cần lấy đi các từ khóa async từ tuyên bố tài sản.

Nhưng thực tế là async không hợp pháp về thuộc tính là một đầu mối khác mà bạn nên viết phương pháp chứ không phải thuộc tính.

Note Từ khóa async không thực sự cần thiết trong mã bạn đã đăng, vì bạn đang không thực sự sử dụng từ khóa await trong đó. Như vậy, bạn chỉ có thể xóa hoàn toàn từ khóa async vì không cần thiết. Trong thực tế, nếu bạn đã thay đổi điều này sang một phương thức, trình biên dịch sẽ cho bạn biết rằng nó là không cần thiết vì bạn không sử dụng await. (Đã xóa sau khi OP đã chỉnh sửa câu hỏi.)

+0

oh chờ đợi! Tôi đang sử dụng đang chờ đợi! sẽ sử dụng await như guy ở đây đã làm: http://stackoverflow.com/questions/7929013/making-a-curl-call-in-c-sharp – Saturnix

+0

Nếu tôi loại bỏ các 'await' tôi phải bọc HttpResponseMessage trong một nhiệm vụ - điều đó có nghĩa là tôi phải viết 'chờ đợi' ở đâu đó trong mã ... – Saturnix

+0

Vâng, bạn vẫn không thể viết chống đỡ erties sử dụng 'async', vì vậy' await' cũng phải đi. –

1

Tôi nghĩ rằng this question có liên quan.

Trong các thuộc tính không đồng bộ ngắn không được hỗ trợ.

9

Thuộc tính không đồng bộ không được hỗ trợ. Tôi mô tả một số number of workarounds trên blog của mình.

Trong trường hợp của bạn, có vẻ như asynchronous lazy initialization sẽ là giải pháp tốt (cũng được mô tả trên blog của tôi).

1

Bạn có thể sử dụng một tài sản Lazy mà trả về một nhiệm vụ:

class MyClass 
{ 
    readonly Lazy<Task<string>> _text; 

    public MyClass() 
    { 
     _text = new Lazy<Task<string>>(async() => 
     { 
      //... await something 
      return "Hello!" 
     }); 
    } 

    async Task DoSomething() 
    { 
     var text = await _text.Value; 
     //... 
    } 
} 
Các vấn đề liên quan