Share via


Cannot convert type 'System.Threading.Tasks.Task' to

Question

Friday, August 15, 2014 2:10 PM

Hi

I am attempting Asyn db calls but having a problem unboxing my results.

I have a results DataContract Class

 [DataContractFormat]
    public class DashBoardResults
    {
        [DataMember]
        public IList<DashboardVehicles> DashboardVehicles;
        [DataMember]
        public IList<DashboardStatistics> DashboardStatisics;
}

I call the following method: the line in bold is throwing the error.

Cannot convert type 'System.Threading.Tasks.Task<System.Threading.Tasks.Task>' to 'System.Threading.Tasks.Task<ParagonGroup.DataContracts.Dashboard.DashBoardResults>'

  public async Task<DashBoardResults> GetDashboardWithAdditionalData(string strUserName)
       {
           List<Task> TaskList = new List<Task>();

           Task[] tasks = new Task[2]{
               Task.Factory.StartNew(() => GraphData_WithAdditionalDataStart("iSight_GetGraphData_PlusBreakdown", strUserName)),
               Task.Factory.StartNew(() => GetDashboardFilterOptionsASyncStart(strUserName))
           };
      


           Task.WaitAll(tasks);

           try
           { var resultGraphData = ((Task<DashBoardResults>)(Task<Task>)tasks[0]).Result;
               var resultFilterData = ((Task<Task>)tasks[1]).Result;
           }
           catch (Exception ex)
           {

           }
        


           DashBoardResults ds = new DashBoardResults();


           return ds;

       }
              

The above method in turns calls this on a separate thread, this is returning the result correctly.

  private async Task<DashBoardResults> GraphData_WithAdditionalDataStart(string SprocName, string strUserName)
       {
          
          
           Task[] tasks = new Task[2]{
               Task.Factory.StartNew(() => SubmitRequestToDB_XML(_ConnectionStringName, MethodBase.GetCurrentMethod().DeclaringType.ToString(), MethodBase.GetCurrentMethod().Name.ToString(), SprocName, strUserName, "DashSVC", string.Empty)),
               Task.Factory.StartNew(() => SubmitRequestToDB_XML(_ConnectionStringName, MethodBase.GetCurrentMethod().DeclaringType.ToString(), MethodBase.GetCurrentMethod().Name.ToString(), "iSight_Tags_Select_AllRelevantForUser", strUserName, "DashSVC", string.Empty))
           };



           Task.WaitAll(tasks);

           try
           {
                ReturnResults returnRes = ((Task<ReturnResults>)tasks[0]).Result;
                ReturnResults returnResTags = ((Task<ReturnResults>)tasks[1]).Result;

                DashBoardResults  resultGraphData = GraphData_WithAdditionalData(returnRes, returnResTags,  strUserName);
           }
           catch (Exception ex)
           {
               //Removed for Simplicity

           }

           return resultGraphData;
       }

However my DashboardResults class is return in its own Task<DashboardResults>

I am unable to work out how to get my class back?

Thanks for your help

Tom

All replies (3)

Friday, August 15, 2014 3:11 PM ✅Answered | 1 vote

I think you've gone a little overboard on the task, async stuff.  The purpose of async is to cleanly allow you to call Task-based methods without using the task directly.  You can mix the two together but in an ideal situation it shouldn't be a common situation.  I think once you get the task work cleaned up your problems will be resolved.

Let's start with the GetDashboardWithAdditionalData method.  You're creating 2 tasks, waiting for them to complete and then doing something with the results.  This should accomplish the same thing because when you call the methods each task will start but you're not waiting for them.  The await will block for each result.  This works the same as WaitAll except you don't have to do the casting.

public static async Task<DashBoardResults> GetDashboardWithAdditionalData ( string strUserName )
{
    var task1 = GraphData_WithAdditionalDataStart("iSight_GetGraphData_PlusBreakdown", strUserName);
    var task2 = GetDashboardFilterOptionsASyncStart(strUserName);

    var resultGraphData = await task1;
    var resultFilterData = await task2;                        

    DashBoardResults ds = new DashBoardResults();

    return ds;
}

The same process basically applies for your other methods as well.  Just for demo purposes I replaced the real work with delays.  The first async task should stall for about 6 seconds and the second task 5 seconds.  But since they are running in parallel you should only see about a 6 second delay for both of them to complete.

private static async Task<DashBoardResults> GraphData_WithAdditionalDataStart ( string SprocName, string strUserName )
{
    var task1 = SubmitRequestToDB_XML();
    var task2 = SubmitRequestToDB_XML();

    var returnRes = await task1;
    var returnResTags = await task2;

    return await GraphData_WithAdditionalData(returnRes, returnResTags, strUserName);
}

private static async Task<object> GetDashboardFilterOptionsASyncStart ( string name )
{
    await Task.Delay(5000);

    return new object();
}

private static async Task<ReturnResults> SubmitRequestToDB_XML ()
{
    await Task.Delay(3000);

    return new ReturnResults();
}

private static async Task<DashBoardResults> GraphData_WithAdditionalData ( ReturnResults res, ReturnResults tags, string name )
{
    await Task.Delay(10000);

    return new DashBoardResults();
}

Michael Taylor
http://blogs.msmvps.com/p3net


Friday, August 15, 2014 3:15 PM ✅Answered | 1 vote

You are doing it the wrong way. When a task returns any value, you should use the generic Task<T> type instead of the non-generic Task type.

For example, if the GetDashboardFilterOptionsASyncStart method returns a string:

Task t1 = Task.Factory.StartNew(() => GraphData_WithAdditionalDataStart("iSight_GetGraphData_PlusBreakdown", strUserName));
            Task<string> t2 = Task<string>.Factory.StartNew(() => { return GetDashboardFilterOptionsASyncStart(strUserName); });

            Task.WaitAll(t1, t2);

            try
            {
                string resultFilterData = t2.Result; //resultFilterData is a string, no need to cast
            }
            catch (Exception ex)
            {

            }

Monday, August 25, 2014 8:31 PM

Thanks everyone, this works - sorry for the delay but been on annual leave.