2013-07-31 3 views
5

Я научился ленивым свойствам загрузки в моем репозитории. Теперь я хотел бы сделать это, но мне также нужно загрузить что-то с веб-страницы (используя Httpclient), что означает, что моя собственность будет асинхронной.Lazy load properties with 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; 
    } 
} 

Однако визуальная студия говорит мне, что

«Модификатор асинхронный не действует для этого элемента»

выделив слово «Новости» в первом линия.

Возможно ли это? Или мне нужно написать отдельный метод?

+0

я считать, что у вас есть, используя заявление для System.Threading.Tasks? Кроме того, какая платформа .NET является таргетированием? Это Silverlight? - Ничего, просто увидел, что это свойство. Вы захотите преобразовать это в методы. –

+0

Мне кажется, что свойство 'News' будет интуитивно иметь тип' List ', украшение' Task <> 'здесь не кажется естественным. Почему вы чувствуете, что вам нужно разоблачить «Задачу <>»? –

+0

@AndrewCoonce На самом деле, если он хочет написать метод асинхронного *, он определенно должен будет записать его как возвращающее задачу. –

ответ

5

Прежде всего, свойства с побочными эффектами обычно не так уж и хороши.

В этом случае просто , читающий, это свойство будет запускать поток, некоторый сетевой трафик и некоторую обработку на удаленном сервере.

Это должен быть метод, а не свойство.

Во-вторых, компилятор прав, свойства не могут быть асинхронными. Теперь вы можете указать свойство, которое возвращает асинхронную задачу, но вам не разрешено использовать ключевое слово async. В основном просто заберите ключевое слово async из объявления свойства.

Но тот факт, что async не является законным по свойствам, является еще одной подсказкой, что вы должны написать метод, а не свойство.

Примечание async ключевое слово на самом деле не требуется в коде, вы в курсе, так как вы на самом деле не используя await ключевое слово там. Таким образом, вы можете просто удалить ключевое слово async, так как оно не требуется. На самом деле, если вы должны изменить это на метод, компилятор скажет вам, что это не нужно, так как вы не используете await. (Удалено после того, как ОР редактировал вопрос.)

+0

oh wait! Я использую await! httpclient будет использовать, как парень здесь: http://stackoverflow.com/questions/7929013/making-a-curl-call-in-c-sharp – Saturnix

+0

Если я удалю «ожидание», я должен обернуть HttpResponseMessage в задаче - что означает, что я должен написать «ждут» где-то в коде ... – Saturnix

+0

Ну, вы все еще не можете писать опору ersies с использованием 'async', поэтому' await' также должен идти. –

1

Я думаю, this question связан.

Вкратце - свойства асинхронизации не поддерживаются.

9

Асинхронные свойства не поддерживаются. Я описываю number of workarounds в своем блоге.

В вашем случае это звучит так: asynchronous lazy initialization будет хорошим решением (также описанным в моем блоге).

1

Вы можете использовать Ленивый свойство, которое возвращает задачу:

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; 
     //... 
    } 
}