Мы пытаемся кэшировать данные службы WCF. Поэтому, когда данные доступны в кэш-памяти, нам нужно вернуть кэшированные данные из кэша как AsyncResult, поскольку данные являются типом объекта, а метод Start — IAsyncResult.
Здесь я не могу изменить возвращаемый тип, потому что это абстрактный член вспомогательного класса.
Кроме того, я не могу проверить наличие кэширования родительской страницы и передать его, потому что это необходимо изменить глобально, чтобы те, кто использует эту услугу, могли ее использовать.
public override IAsyncResult Start(object sender, EventArgs e, AsyncCallback cb, object extraData)
{
if (cache.Get("key")
{
//Needs to return the result Async format which is there as object in cache.
}
svc = new service.GetData(m_url);
if (m_debug_mode) // not thread safe
{
return ((service.GetData)svc).BeginCallDataDebug(request, cb, extraData);
}
return ((service.GetData)svc).BeginCallData(request, cb, extraData);
}
public override void End(IAsyncResult ar)
{
try
{
data = ((service.GetData)m_svc).EndCallData(ar);
if (data !=null)
cache.Add("key", data, null, absoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
}
catch(Exception ex)
{
Log(ex.message);
}
}





System.Threading.Tasks.Task реализует IAsyncResult.
Если данные найдены в кеше, вы можете вернуть завершенный Task с результатом через Task.FromResult. В противном случае вы звоните в сервис.
public override IAsyncResult Start(object sender, EventArgs e, AsyncCallback cb, object extraData)
{
Object cachedData = cache.Get("key");
if (cachedData != null)
{
// Return cached data.
return Task.FromResult<object>(cachedData);
}
// Make call to the service.
svc = new service.GetData(m_url);
if (m_debug_mode) // not thread safe
{
return ((service.GetData)svc).BeginCallDataDebug(request, cb, extraData);
}
return ((service.GetData)svc).BeginCallData(request, cb, extraData);
}
В методе End вы можете проверить тип IAsyncResult, чтобы получить доступ к значению результата.
(Или вы устанавливаете флаг/поле состояния в методе Start о том, вызывали ли вы службу или нет; вы можете проверить поле службы svc, которое будет пустым при использовании кэшированных данных.)
public override void End(IAsyncResult ar)
{
try
{
Task<object> task = ar as Task<object>;
if (task != null)
{
data = task.Result;
}
else
{
data = ((service.GetData)m_svc).EndCallData(ar);
if (data !=null)
cache.Add("key", data, null, absoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
}
}
}
catch(Exception ex)
{
Log(ex.message);
}
}
Но я столкнулся с одной проблемой: при инициализации службы она будет установлена на 10-секундный тайм-аут, поскольку мы берем данные из кеша, если svc не инициализирован, в таком случае он выдает ноль в случае установки журнала тайм-аута.
возвращая результат из Task, задача результата становится активной в серверной части, и это похоже на тупик, и время ожидания службы истекает. В любом случае, чтобы исправить это?
Можете ли вы опубликовать новый вопрос с этим? Нам потребуются некоторые подробности о том, как служба используется в таком сценарии. На данный момент я не вижу, как служба задействована в случае обнаружения данных в кеше.
Я надеюсь, что смогу дать вам награду через три часа после принятия ответа. Вы действительно решили мою проблему, приятель. Большое спасибо за это. Я пропустил основную концепцию самой задачи и асинхронности.