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

时间:2019-03-26 17:41:20

标签: c# asynchronous task

我有以下代码:

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>>的身份返回通话方法。

这是另一个类的“副本”,它们具有相似的逻辑,但以同步方式。想法是改变一些方法 因此它们可以同步运行。

谢谢!

2 个答案:

答案 0 :(得分:0)

    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});
}

答案 1 :(得分:0)

如果您有一个像数组那样的SELECT * WHERE MyDateTimeField) Between #3/24/2018 00:00:00 AM# And #3/24/2018 23:59:59#); ,则可以使用Linq-Methode IEnumerable<A>

将其转换为IEnumerable<object>
Cast<object>()