Постоянные свойства - асинхронно - PullRequest
0 голосов
/ 09 марта 2009

В классическом 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 я мог бы выбрать использование изолированного хранилища в качестве механизма персистентности, но вызов службы не может быть выполнен подобным образом, потому что служба WCF должна вызываться асинхронно.

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

Спасибо, Mark

Ответы [ 2 ]

0 голосов
/ 10 марта 2009

Спасибо за вашу помощь 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 и большей привязки.

0 голосов
/ 09 марта 2009

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

EDIT

На самом деле, цикл занятости / ожидания, вероятно, не тот путь, если веб-служба поддерживает семантику BeginGetData / EndGetData. Я посмотрел на некоторый мой код, где я делаю что-то похожее, и я использую WaitOne, чтобы просто дождаться асинхронного результата и затем получить его. Если ваш веб-сервис не поддерживает это, тогда добавьте 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...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...