2009-03-09 2 views
0

В классическом ASP.NET я сохраняются данные, извлеченные из веб-службы в базовом классе собственности следующим образом:сохранялось свойства - асинхронно

private string m_stringData; 
    public string _stringData 
    { get { 
      if (m_stringData==null) 
       { 
        //fetch data from my web service 
        m_stringData = ws.FetchData() 
       } 
      return m_stringData; 
     } 
    } 

Таким образом, я мог бы просто сделать ссылку на _stringData и знать, что Я всегда получаю данные, которые я получил (возможно, иногда я использую состояние сеанса как хранилище вместо частной переменной-члена).

В Silverlight с WCF я могу использовать изолированное хранилище в качестве моего механизма persistent, но вызов службы не может быть выполнен так, потому что служба WCF должна быть вызвана асинхронно.

Как я могу вызвать вызов службы и получить ответ одним способом?

Спасибо, Марк

ответ

0

В вашем методе, вызовите вызов службы асинхронно и зарегистрировать функцию обратного вызова, которая устанавливает флаг. После вызова метода введите цикл занятости/ожидания, периодически проверяя флаг, пока не будет установлен флаг, указывающий, что данные были возвращены. Обратный вызов должен установить поле поддержки для вашего метода, и вы сможете вернуть его, как только обнаружите, что флаг установлен с указанием успеха. Вы также должны быть обеспокоены неудачей. Если вы можете получить несколько вызовов к вашему методу из разных потоков, вам также потребуется использовать некоторую блокировку, чтобы сделать ваш код потокобезопасным.

EDIT

На самом деле, занят/ожидание цикла, вероятно, не путь, если веб-служба поддерживает BeginGetData/EndGetData семантику. Я посмотрел на некоторые из моего кода, где я делаю что-то подобное, и я использую WaitOne, чтобы просто ждать результата async и затем извлекать его. Если ваш веб-сервис не поддерживает это, то бросьте Thread.Sleep - скажем, на 50-100 мс - в цикле ожидания, чтобы дать время для выполнения других процессов.

Пример из моего кода:

IAsyncResult asyncResult = null; 
try 
{ 
    asyncResult = _webService.BeginGetData(searchCriteria, null, null); 
    if (asyncResult.AsyncWaitHandle.WaitOne(_timeOut, false)) 
    { 
     result = _webService.EndGetData(asyncResult); 
    } 
} 
catch (WebException e) 
{ 
    ...log the error, clean up... 
} 
+0

Спасибо, что нашли время ответить, но я попробовал это ранее и обнаружил, что мой цикл ожидания (do {// stuff} while (blnWaiting == true)} блокировал поток, поэтому флаг никогда не устанавливался , Я ограничен 300 символами в этом «комментарии», поэтому не могу показать полный код, можете ли вы привести пример? Спасибо, Mark –

+0

Я добавил пример из того, как я на самом деле это делаю - это отличается от того, что я описал. Это может быть или не быть применимым в зависимости от вашего веб-сервиса. – tvanfosson

+0

Да, это похоже на то, что мне нужно. Я реализую это и посмотрю, как я пойду. Спасибо за вашу помощь. –

0

Спасибо за вашу помощь tvanfosson. Я последовал ваш код и также нашли псевдо подобное решение, которое отвечает моим потребностям именно с помощью лямбда-выражения:

private string m_stringData; 
public string _stringData{  
get 
    { 
    //if we don't have a list of departments, fetch from WCF 
     if (m_stringData == null) 
     { 
      StringServiceClient client = new StringServiceClient(); 
      client.GetStringCompleted += 
       (sender, e) => 
       { 
        m_stringData = e.Result; 
       }; 
      client.GetStringAsync(); 
     } 
     return m_stringData; 
    } 
} 

EDIT

... К сожалению, на самом деле это не работает, либо :-( Я закончил тем, что делал звонки асинхронно и изменял свою логику программирования, чтобы использовать шаблон MVVM и больше привязки.

Смежные вопросы