#c# #asynchronous #task
#c# #асинхронный #задача
Вопрос:
У меня есть следующий код:
public class TardiisServiceAsync
{
private static TardiisServiceAsync instance;
public static TardiisServiceAsync Instance
{
//Singleton
get
{
if (instance == null)
{
instance = new TardiisServiceAsync();
}
return instance;
}
}
public const string CACHE_PREFIX_TARDIIS_SERVICE = "TardiisServiceAsync_";
public static Dictionary<string, Tuple<string, object>> clients = new Dictionary<string, Tuple<string, object>>();
public delegate Task<IEnumerable<object>> GetServiceList(object client, string connectionId, TardiisServiceParameters parameters = null);
public async Task<IEnumerable<object>> GetDemographicGroupsDelegateAsync(object client, string connectionId, TardiisServiceParameters parameters = null)
{
//Returns IEnumerable<object> task
var test = Convert(client.GetType().GetMethod("GetDemographicGroupsAsync").Invoke(client, new object[] { connectionId }));
var result = await test;
return (IEnumerable<object>)resu<
}
public async Task<IdNameObject[]> GetDemographicGroupsAsync()
{
//This task is called from hight level class
Task<IdNameObject[]> cacheValue = null;
string cacheKey = CACHE_PREFIX_TARDIIS_SERVICE Membership.GetUser().UserName "GetDemographicGroupsAsync" GetMarketCode();
if (ConfigurationManager.AppSettings[ConstantsHelper.FIELD_CONFIG_USE_CACHE_KEY] != null amp;amp; bool.Parse(ConfigurationManager.AppSettings[ConstantsHelper.FIELD_CONFIG_USE_CACHE_KEY]))
{
if (HttpContext.Current.Cache[cacheKey] == null)
{
var taskResult = InitializeTardiisInstanceAndCallService(GetDemographicGroupsDelegateAsync);
var test = await taskResu<
cacheValue = (Task<IdNameObject[]>)HttpContext.Current.Cache[cacheKey];//This is not implemented yet
}
}
return await cacheValue;
}
public static Task<T> Convert<T>(T value)
{
return Task.FromResult<T>(value);
}
public static EnumHelper.EnumMarketCode GetMarketCode(EnumHelper.EnumMarketCode? marketCode = null)
{
//Returns market code
if (!marketCode.HasValue)
return (EnumHelper.EnumMarketCode.US);
else
return marketCode.Value;
}
private Task<IEnumerable<object>> InitializeTardiisInstanceAndCallService(GetServiceList getServiceList, TardiisServiceParameters parameters = null, EnumHelper.EnumMarketCode? marketCode = null, bool creatingConnectionsForAllCountries = false, string username = "")
{
//Get the instance and call the tardiis correct tardiis service depends on the market code
marketCode = GetMarketCode(marketCode);
MembershipUser membershipUser = Membership.GetUser();
string currentUsername = (membershipUser != null ? membershipUser.UserName : username);
string currentKey = currentUsername "_" marketCode;
if (clients.ContainsKey(currentKey))
{
try
{
//check if the connection is still active, or we should reconnect.
return getServiceList(clients[currentKey].Item2, clients[currentKey].Item1, parameters);
}
catch (Exception) { }
}
//At this point there is no connection, we need to open it.
object client = TardiisServiceFactory.GetService(marketCode.Value);
UserDTO userDTO = UserService.Instance.GetByUsername(currentUsername);
TardiisUserDTO tardiisUserDTO = UserService.Instance.GetTardiisUserByUserIdAndMarketCode(userDTO.ID, marketCode.Value.ToString());
if (tardiisUserDTO.TardiisUsername == null)
{
if (creatingConnectionsForAllCountries)
return null;
else
throw new TardiisLoginException("Please enter your credentials");
}
object user = TardiisServiceFactory.GetUser(marketCode.Value, tardiisUserDTO.TardiisUsername, tardiisUserDTO.TardiisPassword);
string connectionId;
try
{
connectionId = (string)client.GetType().GetMethod("InitConnection").Invoke(client, new object[] { user });
}
catch (FaultException ex)
{
// This exception is catched globally by BaseController and prompts the user to enter his
// tardiis credentials again
throw new TardiisLoginException(ex.InnerException.Message, ex);
}
catch (TargetInvocationException ex)
{
// This exception is catched globally by BaseController and prompts the user to enter his
// tardiis credentials again
throw new TardiisLoginException(ex.InnerException.Message, ex);
}
clients[currentKey] = new Tuple<string, object>(connectionId, client);
return getServiceList(clients[currentKey].Item2, clients[currentKey].Item1, parameters);
}
private void AddToCache(string key, object value)
{
HttpContext.Current.Cache.Add(key, value, null, DateTime.Now.AddMinutes(30), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
}
Я получаю следующее сообщение об ошибке:
Не удается привести объект типа ‘System.Многопоточность.Задачи.Задача [Система.Объект] для ввода ‘System.Коллекции.Общий.IEnumerable1[Система.Объект].
Результатом задачи является TypedClass[]
.
Как я могу вернуть как Task<IEnumerable<object>>
при методе вызова.
Это «копия» другого класса, который имеет аналогичную логику, но синхронизированным образом. Идея в том, чтобы изменить некоторые методы, чтобы их можно было запускать синхронно.
Спасибо!
Комментарии:
1. var TaskResult = task.Resu< это не задача, когда вы добавляете .result, это будет перечислимый или другой тип, который вы используете
2. Привет @Pliskin, спасибо за ваш ответ, я понимаю это, но я не могу преобразовать
Task<MyCustomClass>
результат вTask<IEnumerable<object>>
. Спасибо.3. каков тип TaskResult и тип параметра метода convert?
4. Результатом является
Task<TardiisPlanning.TardiisPlanningService.DemographicGroup[]>
массив пользовательского класса. Ниже я оставляю код метода Convert:public static Task<T> Convert<T>(T value) { return Task.FromResult<T>(value); }
5. Проверьте обновленный код и дайте мне знать, работает ли он, или добавьте это как параметр Convert resultado. ToList()
Ответ №1:
public async Task<IEnumerable<object>> GetDemographicGroupsDelegateAsync(object client, string connectionId, TardiisServiceParameters parameters = null)
{
var test = Convert(client.GetType().GetMethod("GetDemographicGroupsAsync").Invoke(client, new object[] { connectionId }));
var result = await test;
var resultado = test.Resu<
return Convert(new List<Object>{resultado});
}
Ответ №2:
Если у вас есть IEnumerable<A>
подобный массив, вы можете преобразовать его в IEnumerable<object>
, используя Linq-метод Cast<object>()
public async Task<IEnumerable<object>> GetDemographicGroupsDelegateAsync(object client, string connectionId, TardiisServiceParameters parameters = null)
{
var test = Convert(client.GetType().GetMethod("GetDemographicGroupsAsync").Invoke(client, new object[] { connectionId }));
var task = await test;
var taskResult = await task;
return taskResult.Cast<object>();
}
Комментарии:
1. Привет, Ackdari, спасибо, но переменная taskResullt является типом объекта и не является awatiable, я прав?.
2. @MarceloArias ну, я не знаю, каковы типы ваших объектов? Возможно, я смогу прояснить свой ответ, если вы скажете мне, что такое тип
test
и что такое типtask
.