C#-<object> 在任务异步调用时返回 IEnumerable



我有以下代码:

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>)result;
    }
    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 && bool.Parse(ConfigurationManager.AppSettings[ConstantsHelper.FIELD_CONFIG_USE_CACHE_KEY]))
        {
            if (HttpContext.Current.Cache[cacheKey] == null)
            {
                var taskResult = InitializeTardiisInstanceAndCallService(GetDemographicGroupsDelegateAsync);
                var test = await taskResult;
                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.Threading.Tasks.Task[System.Object]"的对象转换为类型"System.Collections.Generic.IEnumerable1[System.Object]。

任务的结果是一个TypedClass[]

如何在调用方法上作为Task<IEnumerable<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 result = await test;
    var resultado = test.Result;
    return Convert(new List<Object>{resultado});
}

如果你有一个像数组这样的IEnumerable<A>,你可以使用 Linq-Methode Cast<object>()将其强制转换为IEnumerable<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>();
}

最新更新