32

I have worked with asynchronous methods and the methods which return multiple values, separately. In this specific situation, following "GetTaskTypeAndId()" method should be asynchronous and should return multiple values at the same time. How should I make this method asynchronous?

        public async Task DeleteSchoolTask(int schoolNumber, int taskDetailId)
        {  
            var result = GetTaskTypeAndId(taskDetailId); // This should be called asynchronously
            int taskId = result.Item1;
            string taskType = result.Item2;

            // step 1: delete attachment physically from server
            var fileService = new FileService(Logger, CurrentUser);
            var relativeFilePath = $"{schoolNumber}\\{Consts.RM_SCHOOL}\\{taskDetailId}";
            fileService.DeleteAttachmentFolderFromServer(Consts.CONFIG_SMP_UPLOADFILE_ROOTPATH, relativeFilePath);

            // step 2: delete records from database
            await _routineMaintenanceRepo.Value.DeleteSchoolTask(taskDetailId);
        }


        public (int, string) GetTaskTypeAndId(int taskDetailId) // How should I write this line using 'async Task'?
        {
            var detailRecord = await _routineMaintenanceRepo.Value.GetDetailRecord(taskDetailId);

            int taskId = 0;
            string taskType = "";

            switch (detailRecord.TaskType)
            {
                case 1:
                    taskId = (int)detailRecord.RoutineMaintenanceTaskId;
                    taskType = Consts.RM_DEFAULT;
                    break;
                case 2:
                    taskId = (int)detailRecord.RoutineMaintenanceTaskDuplicateId;
                    taskType = Consts.RM_DUPLICATE;
                    break;
                case 3:
                    taskId = (int)detailRecord.RoutineMaintenanceTaskSchoolId;
                    taskType = Consts.RM_SCHOOL;
                    break;
                default:
                    break;
            }
            return (taskId, taskType);
        }
Kushan Randima
  • 2,174
  • 5
  • 31
  • 58

2 Answers2

57

After playing with the code I was able to figure it out. Here is the solution.

        public async Task DeleteSchoolTask(int schoolNumber, int taskDetailId)
        {  
            var result = await GetTaskTypeAndId(taskDetailId);
            int taskId = result.Item1;
            string taskType = result.Item2;

            // step 1: delete attachment physically from server
            var fileService = new FileService(Logger, CurrentUser);
            var relativeFilePath = $"{schoolNumber}\\{Consts.RM_SCHOOL}\\{taskDetailId}";
            fileService.DeleteAttachmentFolderFromServer(Consts.CONFIG_SMP_UPLOADFILE_ROOTPATH, relativeFilePath);

            // step 2: delete records from database
            await _routineMaintenanceRepo.Value.DeleteSchoolTask(taskDetailId);
        }

        public async Task<(int, string)> GetTaskTypeAndId(int taskDetailId)
        {
            var detailRecord = await _routineMaintenanceRepo.Value.GetDetailRecord(taskDetailId);

            int taskId = 0;
            string taskType = "";

            switch (detailRecord.TaskType)
            {
                case 1:
                    taskId = (int)detailRecord.RoutineMaintenanceTaskId;
                    taskType = Consts.RM_DEFAULT;
                    break;
                case 2:
                    taskId = (int)detailRecord.RoutineMaintenanceTaskDuplicateId;
                    taskType = Consts.RM_DUPLICATE;
                    break;
                case 3:
                    taskId = (int)detailRecord.RoutineMaintenanceTaskSchoolId;
                    taskType = Consts.RM_SCHOOL;
                    break;
                default:
                    break;
            }
            return (taskId, taskType);
        }
Kushan Randima
  • 2,174
  • 5
  • 31
  • 58
  • 1
    This code in C# 7.0 will return an compiler error along the lines: "Predefined type System.ValueTuple not defined or imported" See either https://intellitect.com/fix-system-valuetuple-error/ or the answers of https://stackoverflow.com/questions/38382971/predefined-type-system-valuetuple%C2%B42%C2%B4-is-not-defined-or-imported – TazAstroSpacial Feb 03 '20 at 03:07
  • Thank you for figuring this out. Did U get a chance to install System.ValueTuple from Nuget Manager in order to fix this issue? If that did not help you, please let me know, I will look for another solution for you. Cheers! – Kushan Randima Feb 03 '20 at 23:04
2

In C# 7 onwards, you can use implicit named tuples using System.ValueTuple (basically same as in the Kushan Randima answer but with explicit member names):

public async Task<(int TaskId, string TaskType)> GetTaskTypeAndIdAsync(...)
{
    ...
    var someInt = 123;
    var someStr = "abc";
    ...
    return (someInt, someStr);
}

public async Task FuncAsync(...)
{
    ...
    var result = await GetTaskTypeAndIdAsync(...);
    DoSomethingWith(result.TaskId);
    DoSomethingWith(result.TaskType);
    ...
}

See this question for reference.

Sinipelto
  • 147
  • 1
  • 8