Fundamentals of Methodical Tasks

Introduction

As done with value types and strings, a task can be performed on an object of a class. You can start by creating a class. You must then create a method that returns an object of the same class. Here is an example:

using static System.Console;
using System.Collections.Generic;

public class Exercise
{
    public static int Main()
    {
            return 1;
    }

    public Semester Register()
    {
            return new Semester() { Course1 = 79, Course2 = 92, Course3 = 68, Course4 = 84, Course5 = 61 };        
    }

    public class Semester
    {
        public int Course1 { get; set; }
        public int Course2 { get; set; }
        public int Course3 { get; set; }
        public int Course4 { get; set; }
        public int Course5 { get; set; }
    }
}

To create a task, declare a Task<> variable that uses the desired class as parameter type. You can initialize the variable with a method that returns an object of the class. Here is an example:

using System.Threading.Tasks;

public class Exercise
{
    public static int Main()
    {
        Task<Semester> grades = new Task<Semester>(Register);

        return 1;
    }

    private static Semester Register()
    {
        return new Semester() { Course1 = 95, Course2 = 77, Course3 = 84, Course4 = 79, Course5 = 68 };
    }
}

public class Semester
{
    public int Course1 { get; set; }
    public int Course2 { get; set; }
    public int Course3 { get; set; }
    public int Course4 { get; set; }
    public int Course5 { get; set; }
}

You can then call the Task.Start() method to launch the task. The Task<>.Result property produces an object of the class used as parameter. As a result, when you access that property, the Intellisense is aware of the members of that class and can appropriately assist you. Here is an example:

using static System.Console;
using System.Threading.Tasks;

public class Exercise
{
    public static int Main()
    {
        double gpa = 0.00;

        Task<Semester> grades = new Task<Semester>(() =>
        {
            return new Semester() { Course1 = 95, Course2 = 77, Course3 = 84, Course4 = 79, Course5 = 68 };
        });

        grades.Start();

        double crs1GPA = grades.Result.Course1 / 25.00;
        double crs2GPA = grades.Result.Course2 / 25.00;
        double crs3GPA = grades.Result.Course3 / 25.00;
        double crs4GPA = grades.Result.Course4 / 25.00;
        double crs5GPA = grades.Result.Course5 / 25.00;

        WriteLine("Semester GPA = " + ((crs1GPA + crs2GPA + crs3GPA + crs4GPA + crs5GPA) / 5).ToString("F"));

        return 1;
    }

    private static Semester Register()
    {
        return new Semester() { Course1 = 95, Course2 = 77, Course3 = 84, Course4 = 79, Course5 = 68 };
    }
}

public class Semester
{
    public int Course1 { get; set; }
    public int Course2 { get; set; }
    public int Course3 { get; set; }
    public int Course4 { get; set; }
    public int Course5 { get; set; }
}

This would produce:

Semester GPA = 3.22
Press any key to continue . . .

Once again, you can define the function directly where it is needed (instead of defining it separately). Here is an example:

Task<Semester> grades = new Task<Semester>(() =>
{
    return new Semester() { Course1 = 95, Course2 = 77, Course3 = 84, Course4 = 79, Course5 = 68 };
});

Practical LearningPractical Learning: Introducing Functional Tasks

  1. Start Microsoft Visual Studio
  2. On the main menu, click File -> New -> Project...
  3. In the New Project dialog box, click Console App (.NET Framewoork) and change the project Name to RedOakHighSchool2
  4. Click OK
  5. In the Solution Explorer, right-click Program.cs -> Rename
  6. Type AcademicsManagement to get AcademicsManagement.cs, and press Enter
  7. Read the text in the message box and press Enter
  8. Change the document as follows:
    using System;
    using System.Threading.Tasks;
    
    namespace RedOakHighSchool2
    {
        public class Program
        {
            static        int number = -1;
    
            public static int Main(string[] args)
            {
                int iCourse1Sem1NumericGrade = 0;
                int iCourse2Sem1NumericGrade = 0;
                int iCourse3Sem1NumericGrade = 0;
                int iCourse4Sem1NumericGrade = 0;
                int iCourse5Sem1NumericGrade = 0;
    
                Console.Title = "Red Oak High School";
                Console.WriteLine("Red Oak High School");
                Console.WriteLine("===================================");
                Console.WriteLine("Type the grades for the 1st semester");
                Console.Write("Algebra 1:         ");
                iCourse1Sem1NumericGrade = int.Parse(Console.ReadLine());
                Console.Write("English:           ");
                iCourse2Sem1NumericGrade = int.Parse(Console.ReadLine());
                Console.Write("Social Science:    ");
                iCourse3Sem1NumericGrade = int.Parse(Console.ReadLine());
                Console.Write("Physical Science:  ");
                iCourse4Sem1NumericGrade = int.Parse(Console.ReadLine());
                Console.Write("History/Geography: ");
                iCourse5Sem1NumericGrade = int.Parse(Console.ReadLine());
    
                number = iCourse1Sem1NumericGrade;
    
    
                Func<char> GetCourse2LetterGrade = () =>
                {
                    if (iCourse2Sem1NumericGrade >= 90)
                        return 'A';
                    else if (iCourse2Sem1NumericGrade >= 80)
                        return 'B';
                    else if (iCourse2Sem1NumericGrade >= 70)
                        return 'C';
                    else if (iCourse2Sem1NumericGrade >= 65)
                        return 'D';
    
                    return 'F';
                };
    
    
                Task<char> processCourse1Sem1NumericGrade = new Task<char>(GetCourse1LetterGrade);
                Task<char> processCourse2Sem1NumericGrade = new Task<char>(GetCourse2LetterGrade);
    
                Task<char> processCourse3Sem1NumericGrade = new Task<char>(() =>
                {
                    if (iCourse3Sem1NumericGrade >= 90)
                        return 'A';
                    else if (iCourse3Sem1NumericGrade >= 80)
                        return 'B';
                    else if (iCourse3Sem1NumericGrade >= 70)
                        return 'C';
                    else if (iCourse3Sem1NumericGrade >= 65)
                        return 'D';
    
                    return 'F';
                });
    
                processCourse1Sem1NumericGrade.Start();
                processCourse2Sem1NumericGrade.Start();
                processCourse3Sem1NumericGrade.Start();
    
                Func<char> GetCourse4LetterGrade = () =>
                {
                    if (iCourse4Sem1NumericGrade >= 90)
                        return 'A';
                    else if (iCourse4Sem1NumericGrade >= 80)
                        return 'B';
                    else if (iCourse4Sem1NumericGrade >= 70)
                        return 'C';
                    else if (iCourse4Sem1NumericGrade >= 65)
                        return 'D';
    
                    return 'F';
                };
    
                Task<char> processCourse4Sem1NumericGrade = Task<char>.Run<char>(GetCourse4LetterGrade);
                Task<char> processCourse5Sem1NumericGrade = Task<char>.Run<char>(() =>
                {
                    if (iCourse5Sem1NumericGrade >= 90)
                        return 'A';
                    else if (iCourse5Sem1NumericGrade >= 80)
                        return 'B';
                    else if (iCourse5Sem1NumericGrade >= 70)
                        return 'C';
                    else if (iCourse5Sem1NumericGrade >= 65)
                        return 'D';
    
                    return 'F';
                });
    
                Console.WriteLine("===================================");
                Console.WriteLine("Semester 1 - Grades Report");
                Console.WriteLine("---------------------------------");
                Console.WriteLine("Algebra 1:         {0}", processCourse1Sem1NumericGrade.Result);
                Console.WriteLine("English:           {0}", processCourse2Sem1NumericGrade.Result);
                Console.WriteLine("Social Science:    {0}", processCourse3Sem1NumericGrade.Result);
                Console.WriteLine("Physical Science:  {0}", processCourse4Sem1NumericGrade.Result);
                Console.WriteLine("History/Geography: {0}", processCourse5Sem1NumericGrade.Result);
    
                Console.WriteLine("===================================");
                return 0;
            }
    
            public static char GetCourse1LetterGrade()
            {
                if (number >= 90)
                    return 'A';
                else if (number >= 80)
                    return 'B';
                else if (number >= 70)
                    return 'C';
                else if (number >= 65)
                    return 'D';
    
                return 'F';
            }
    
        }
    }
  9. To execute the application, on the main menu, click Debug -> Start Without Debugging:
    Red Oak High School
    ===================================
    Type the grades for the 1st semester
    Algebra 1:
  10. When prompted, type some values as follows:
    Red Oak High School
    ===================================
    Type the grades for the 1st semester
    Algebra 1:         58
    English:           72
    Social Science:    55
    Physical Science:  86
    History/Geography: 46
  11. Make sure you press after the last grade to display the summary:
    Red Oak High School
    ===================================
    Type the grades for the 1st semester
    Algebra 1:         58
    English:           72
    Social Science:    55
    Physical Science:  86
    History/Geography: 46
    ===================================
    Semester 1 - Grades Report
    ---------------------------------
    Algebra 1:         F
    English:           C
    Social Science:    F
    Physical Science:  B
    History/Geography: F
    ===================================
    Press any key to continue . . .
  12. Close the browser and return to your programming environment

A Task as Argument

As mentioned previously for tasks, Task<> can be used as a type.

To create a method that uses a parameter of a task type, in the parentheses of the method, type Task<>, include its parameter type, and follow it with a name for the parameter. In the body of the method, ignore the parameter if you don't need it. Otherwise, you can get the value of the parameter. For example, you can initialize it with a value or a method that produces its type of task. Here is an example:

public class Summary
{
    private void GetCourseGrade(Task<char> grade)
    {
        grade = new Task<char>(GetLetterGrade);
    }

    public char GetLetterGrade()
    {
        return 'F';
    }
}

You can involve the parameter or its value in any operation or processing you want. You can then use the method any way you want outside its body. Here is an example:

using static System.Console;
using System.Threading.Tasks;

public class Academics
{
    static int number = -1;

    public static int Main()
    {
        number = 85;

        Task<char> courseGradeProcessing = new Task<char>(GetLetterGrade);

        WriteLine("Course Comment: {0}", GetCourseGrade(courseGradeProcessing));
        return 1;
    }

    private static char GetLetterGrade()
    {
        if (number >= 90)
            return 'A';
        else if (number >= 80)
            return 'B';
        else if (number >= 70)
            return 'C';
        else if (number >= 65)
            return 'D';

        return 'F';
    }

    private static string GetCourseGrade(Task<char> grade)
    {
        string comment = string.Empty;

        grade.Start();

        if (grade.Result == 'A')
            comment = "Excellent";
        else if (grade.Result == 'B')
            comment = "Good";
        else if (grade.Result == 'C')
            comment = "Average";
        else if (grade.Result == 'D')
            comment = "Pass";
        else // if (grade.Result == 'F')
            comment = "Fail";

        return comment;
    }
}

This would produce::

Course Comment: Good
Press any key to continue . . .

In the same way, you can pass a task of a class as parameter.

Returning a Valued Task

You can create a method that produces a task. To start this, on the left of the name of the method, specify the return type as Task<>. In the <> operator, specify the data type you want. The method may or may not use parameters. In the body of the method, do what you want. At the end of the method, you must return a task or a value/object compatible with the task. Probably the easiest way to initialize a task in the method is to declare a task variable and initialize it with a value/object or a method that produces a value or object of the parameter type. Here is an example:

using static System.Console;
using System.Threading.Tasks;

public class Academics
{
    int number = -1;

    public char GetLetterGrade()
    {
        return 'F';
    }

    private Task<char> GetCourseGrade()
    {
        Task <char> grade = new Task<char>(GetLetterGrade);

        return grade;
    }
}

When calling the method, you can assign its call to a local Task<> variable and use the value or object of that variable. Here is an example:

using static System.Console;
using System.Threading.Tasks;

public class Academics
{
    static int number = -1;

    public static int Main()
    {
        number = 85;

        Task<char> courseGradeProcessing = GetCourseGrade();

        courseGradeProcessing.Start();

        WriteLine("Course Comment: {0}", courseGradeProcessing.Result);

        return 1;
    }

    private static char GetLetterGrade()
    {
        if (number >= 90)
            return 'A';
        else if (number >= 80)
            return 'B';
        else if (number >= 70)
            return 'C';
        else if (number >= 65)
            return 'D';

        return 'F';
    }

    private static Task<char> GetCourseGrade()
    {
        Task<char> grade = new Task<char>(GetLetterGrade);

        return grade;
    }
}

This would produce:

Course Comment: B
Press any key to continue . . .

Returning a Task as Object

A functional task is one that runs asynchronously. One of the most important features here is that the method may produce an object that is a task. Of course, you must create the method to produce such an object.

To create a method that produces a task, specify its data type as Task<>. Enter the name of the class as the parameter type. Here is an example:

public Task<Models.Semester> GetSemesterGrades()
{
}

As always, before the end of the method, make sure you return an object of type Task<>.

Practical LearningPractical Learning: Introducing Tasks and Classes

  1. In the Solution Explorer, right-click Models -> Add -> Class...
  2. Type Semester as the file name
  3. Click Add
  4. Change the class as follows:
    namespace RedOakHighSchool1.Models
    {
        public class Semester
        {
            public int Course1 { get; set; }
            public int Course2 { get; set; }
            public int Course3 { get; set; }
            public int Course4 { get; set; }
            public int Course5 { get; set; }
        }
    }
  5. Access the AcademicsController.cs tab and change the document as follows:
    using static System.Console;
    using System.Collections.Generic;
    
    
    using System.Threading.Tasks;
    
    namespace RedOakHighSchool102.Controllers
    {
        public class Academics
        {
            int iCourse1Sem1NumericGrade = -1;
            int iCourse2Sem1NumericGrade = -1;
            int iCourse3Sem1NumericGrade = -1;
            int iCourse4Sem1NumericGrade = -1;
            int iCourse5Sem1NumericGrade = -1;
    
            // GET: Academics
    public static int Main()
            {
                return 1;
            }
    
            // GET: Academics/GradeReportStartUp
            public ActionResult GradeReportStartUp()
            {
                return 1;
            }
    
            // GET: Academics/GradeReportPreparation
            public ActionResult GradeReportPreparation(string CourseName1, string Course1Sem1NumericGrade, string Course1Sem2NumericGrade, string Course1Sem3NumericGrade,
                                                       string CourseName2, string Course2Sem1NumericGrade, string Course2Sem2NumericGrade, string Course2Sem3NumericGrade,
                                                       string CourseName3, string Course3Sem1NumericGrade, string Course3Sem2NumericGrade, string Course3Sem3NumericGrade,
                                                       string CourseName4, string Course4Sem1NumericGrade, string Course4Sem2NumericGrade, string Course4Sem3NumericGrade,
                                                       string CourseName5, string Course5Sem1NumericGrade, string Course5Sem2NumericGrade, string Course5Sem3NumericGrade)
            {
                iCourse1Sem1NumericGrade = int.Parse(Course1Sem1NumericGrade);
                iCourse2Sem1NumericGrade = int.Parse(Course2Sem1NumericGrade);
                iCourse3Sem1NumericGrade = int.Parse(Course3Sem1NumericGrade);
                iCourse4Sem1NumericGrade = int.Parse(Course4Sem1NumericGrade);
                iCourse5Sem1NumericGrade = int.Parse(Course5Sem1NumericGrade);
    
                Func<char> GetCourse2LetterGrade = () =>
                {
                    if (iCourse2Sem1NumericGrade >= 90)
                        return 'A';
                    else if (iCourse2Sem1NumericGrade >= 80)
                        return 'B';
                    else if (iCourse2Sem1NumericGrade >= 70)
                        return 'C';
                    else if (iCourse2Sem1NumericGrade >= 65)
                        return 'D';
    
                    return 'F';
                };
    
                Task<char> processCourse1Sem1NumericGrade = new Task<char>(GetCourse1LetterGrade);
                Task<char> processCourse2Sem1NumericGrade = new Task<char>(GetCourse2LetterGrade);
    
                Task<char> processCourse3Sem1NumericGrade = new Task<char>(() =>
                {
                    if (iCourse3Sem1NumericGrade >= 90)
                        return 'A';
                    else if (iCourse3Sem1NumericGrade >= 80)
                        return 'B';
                    else if (iCourse3Sem1NumericGrade >= 70)
                        return 'C';
                    else if (iCourse3Sem1NumericGrade >= 65)
                        return 'D';
    
                    return 'F';
                });
    
                processCourse1Sem1NumericGrade.Start();
                processCourse2Sem1NumericGrade.Start();
                processCourse3Sem1NumericGrade.Start();
    
                ViewBag.Course1Sem1LetterGrade = processCourse1Sem1NumericGrade.Result;
                ViewBag.Course2Sem1LetterGrade = processCourse2Sem1NumericGrade.Result;
                ViewBag.Course3Sem1LetterGrade = processCourse3Sem1NumericGrade.Result;
    
                Func<char> GetCourse4LetterGrade = () =>
                {
                    if (iCourse4Sem1NumericGrade >= 90)
                        return 'A';
                    else if (iCourse4Sem1NumericGrade >= 80)
                        return 'B';
                    else if (iCourse4Sem1NumericGrade >= 70)
                        return 'C';
                    else if (iCourse4Sem1NumericGrade >= 65)
                        return 'D';
    
                    return 'F';
                };
    
                Task<char> processCourse4Sem1NumericGrade = Task<char>.Run<char>(GetCourse4LetterGrade);
                Task<char> processCourse5Sem1NumericGrade = Task<char>.Run<char>(() =>
                {
                    if (iCourse5Sem1NumericGrade >= 90)
                        return 'A';
                    else if (iCourse5Sem1NumericGrade >= 80)
                        return 'B';
                    else if (iCourse5Sem1NumericGrade >= 70)
                        return 'C';
                    else if (iCourse5Sem1NumericGrade >= 65)
                        return 'D';
    
                    return 'F';
                });
    
                ViewBag.Course4Sem1LetterGrade = processCourse4Sem1NumericGrade.Result;
                ViewBag.Course5Sem1LetterGrade = processCourse5Sem1NumericGrade.Result;
    
                Task<Models.Semester> sem1Grades = GetSemesterGrades();
    
                sem1Grades.Start();
    
                double crs1GPA = (sem1Grades.Result.Course1 / 25.00);
                double crs2GPA = (sem1Grades.Result.Course2 / 25.00);
                double crs3GPA = (sem1Grades.Result.Course3 / 25.00);
                double crs4GPA = (sem1Grades.Result.Course4 / 25.00);
                double crs5GPA = (sem1Grades.Result.Course5 / 25.00);
    
                ViewBag.Semester1NumericGPA = ((crs1GPA + crs2GPA + crs3GPA + crs4GPA + crs5GPA) / 5).ToString();
    
                double semester1Average = (iCourse1Sem1NumericGrade + iCourse2Sem1NumericGrade + iCourse3Sem1NumericGrade + iCourse4Sem1NumericGrade + iCourse5Sem1NumericGrade) / 5.00;
    
                Task<char> semester1LetterGPA = Task<char>.Run<char>(() =>
                {
                    if (semester1Average >= 90)
                        return 'A';
                    else if (semester1Average >= 80)
                        return 'B';
                    else if (semester1Average >= 70)
                        return 'C';
                    else if (semester1Average >= 65)
                        return 'D';
    
                    return 'F';
                });
    
                ViewBag.Semester1LetterGPA = semester1LetterGPA.Result;
                
                return 1;
            }
    
            public char GetCourse1LetterGrade()
            {
                if (iCourse1Sem1NumericGrade >= 90)
                    return 'A';
                else if (iCourse1Sem1NumericGrade >= 80)
                    return 'B';
                else if (iCourse1Sem1NumericGrade >= 70)
                    return 'C';
                else if (iCourse1Sem1NumericGrade >= 65)
                    return 'D';
    
                return 'F';
            }
    
            public Models.Semester RegisterSemester1()
            {
                Models.Semester sem = new Models.Semester() { Course1 = iCourse1Sem1NumericGrade, Course2 = iCourse2Sem1NumericGrade, Course3 = iCourse3Sem1NumericGrade, Course4 = iCourse4Sem1NumericGrade, Course5 = iCourse5Sem1NumericGrade };
    
                return sem;
            }
    
            public Task<Models.Semester> GetSemesterGrades()
            {
                Task<Models.Semester> grades = new Task<Models.Semester>(RegisterSemester1);
    
                return grades;
            }
        }
    }
  6. Access the GradeReportPreparation.cshtml tab and change the document as follows:
        Title = "Grade Report Start-Up";
    }
    
    <h1>Red Oak High School</h1>
    <h2>Grade Report Start-Up</h2>
    
    @using (Html.BeginForm("GradeReportPreparation", "Academics", FormMethod.Post))
    {
        <table border="6">
            <tr>
                <td style="font-weight: 600;">Course Name</td>
                <td style="text-align: center; font-weight: bold"><b>Numeric Grade</b></td>
            </tr>
            <tr>
                <td>@Html.TextBox("CourseName1", "Math")</td>
                <td style="text-align: center">@Html.TextBox("Course1Sem1NumericGrade", "0", new { style = "width: 60px;" })</td>
            </tr>
            <tr>
                <td>@Html.TextBox("CourseName2", "English")</td>
                <td style="text-align: center">@Html.TextBox("Course2Sem1NumericGrade", "0", new { style = "width: 60px;" })</td>
            </tr>
            <tr>
                <td>@Html.TextBox("CourseName3", "Social Science")</td>
                <td style="text-align: center">@Html.TextBox("Course3Sem1NumericGrade", "0", new { style = "width: 60px;" })</td>
            </tr>
            <tr>
                <td>@Html.TextBox("CourseName4", "Physical Science")</td>
                <td style="text-align: center">@Html.TextBox("Course4Sem1NumericGrade", "0", new { style = "width: 60px;" })</td>
            </tr>
            <tr>
                <td>@Html.TextBox("CourseName5", "History/Geography")</td>
                <td style="text-align: center">@Html.TextBox("Course5Sem1NumericGrade", "0", new { style = "width: 60px;" })</td>
            </tr>
        </table>
        <hr />
        <p style="width: 600px;"><input type="submit" name="btnPrepareGradeReport" value="Prepare Grade Report" style="width: 300px" /></p>
    }
  7. Click the GradeReportStartUp.cshtml tab to activate it
  8. To execute the project, on the main menu, click Debug -> Start Without Debugging
  9. On the form, replace English with English Litterature
  10. Change the grades as follows:
    Course Name	Numeric Grade
    Math			    95
    English Litterature			77
    Social Science	84
    Chemistry		    79
    History/Geography	68
  11. Click the Prepare Grade Report button
  12. Close the browser and return to your programming environment

Asynchrony in an Application

Introduction

In our introduction to synchronous operations, we saw how important it is to think about threads (and processes) competing for the same resources. An example is about two sources (such as two people) trying to access the same bank account, on purpose or by mistake, at the same time. Another example is when a certain operation needs to use many resources at the same time. One more example is for an operation that must take a long time to complete. In these and other situations, you as a programmer should write code that performs operations that do not interfere with other operations. Such operations are referred to as asynchronous operations. The code that takes care of this can be written for a method, a lambda expression, or in exception handling.

We saw that, when anticipating one or more oprations that must be performed asynchronously, you can (should) create a method that returns a Task<> object. Here is an example:

using System.Threading.Tasks;

public class Exercise
{
    // This number represents the numeric grade of a student.
    static int number = -1;

    public static int Main()
    {
        /* In a typical application (or a Web app for a school, the students grades 
         * may come from different sources, sometimes from computers in different locations... */
        number = 82;

        return 1;
    }

    public char GetLetterGrade()
    {
        if (number >= 90)
            return 'A';
        else if (number >= 80)
            return 'B';
        else if (number >= 70)
            return 'C';
        else if (number >= 65)
            return 'D';

        return 'F';
    }

    private Task<char> GetCourseGrade()
    {
        Task<char> grade = new Task<char>(GetLetterGrade);

        return grade;
    }
}

Introduction to Asynchronous Methods

As you may know by now, the primary section of code that performs an assignment is the method of a class. Therefore, if you want to take care of a(n) asynchronous operation(s), the primary place to do this is the method.

To let you create a method that addresses concerns for one or more asynchronous operations, the C# language provides the async keyword. To start the method, precede its return type with the async keyword. The formula to follow is:

public async data-type method-name(parameter(s))
{
}

The primary job of an asynchronous method is to avoid interferring with other operations. We saw that, to make this possible, you can create a method that returns a task. Such a method can (must) return a Task<> object. If the operation must produce a regular value (a number, a character, or a Boolean value) or a string, specify the desired type between < and >. In this case, pass the data type as the parameter type. Here is an example:

public async Task<string> StudentComments()
{
}

If the method must produce an object, specify the class name as the parameter type of Task<>. Here is an example:

using System.Threading.Tasks;

public class Exercise
{
    // This number represents the numeric grade of a student.
    static int number = -1;

    public static int Main()
    {
        number = 82;

        return 1;
    }

    public char GetLetterGrade()
    {
        if (number >= 90)
            return 'A';
        else if (number >= 80)
            return 'B';
        else if (number >= 70)
            return 'C';
        else if (number >= 65)
            return 'D';

        return 'F';
    }

    private Task<char> GetCourseGrade()
    {
        Task<char> grade = new Task<char>(GetLetterGrade);

        return grade;
    }

    private async Task<Semester> GradeReport()
    {
    }
}

public class Semester
{
    public int Course1 { get; set; }
    public int Course2 { get; set; }
    public int Course3 { get; set; }
    public int Course4 { get; set; }
    public int Course5 { get; set; }
}

In both cases, the method may or may not use parameters, it is up to you. Other than that, if you are not planning to use the return value of the method, you can return null. Here are examples:

public async Task<string> StudentComments()
{
    return null;
}

private async Task<Semester> GradeReport()
{
    return null;
}

You can also return an object of the parameter type. Here are two examples:

using System.Threading.Tasks;

public class Exercise
{
    public async Task<string> StudentComments()
    {
	    return "Nothing";
	}

	private async Task<Semester> GradeReport()
    {
        return new Semester();
    }

    private async Task<Semester> GradeSummary()
    {
        return new Semester("SPRING 2018");
    }
}

public class Semester
{
    private string sName;

    public Semester()
    {

    }

    public Semester(string semName)
    {
        sName = semName;
    }
}

Depending on what is going on, you can also return an object of a class derived from the parameter type.

In the method that anticipates an asynchronous operation, which is the async method, you must indicate where the long operation is performed. This is done by calling the method that performs the task.

To let you indicate the method that performs the arduous operation, the C# language provides the await keyword. When calling the method that performs the long operation, precede it with that keyword. Here is an example:

using System.Threading.Tasks;

public class Operations
{
    public char GetLetterGrade()
    {
        return 'F';
    }

    private Task<char> GetCourseGrade()
    {
        Task<char> grade = new Task<char>(GetLetterGrade);

        return grade;
    }

    private async Task<Semester> GradeReport()
    {
        await GetCourseGrade();

        return null;
    }
}

public class Semester
{
}

Most of the time, you will need to get the return value of the called method and use that value or object as you see fit. To get that value, you can declare a local variable and initialize it with the await calling method. Here is an example:

private async Task<Semester> GradeReport()
{
    var summary = await GetCourseGrade();

    return null;
}

You can then use the value as you see fit. For example, if necessary, you can use the returned value when initializing a variable. Here is an example:

using System.Threading.Tasks;

public class ArraysOperations1
{
    static int number = -1;

    public static int Main()
    {
        number = 82;

        return 1;
    }

    public char GetLetterGrade()
    {
        if (number >= 90)
            return 'A';
        else if (number >= 80)
            return 'B';
        else if (number >= 70)
            return 'C';
        else if (number >= 65)
            return 'D';

        return 'F';
    }

    private Task<char> GetCourseGrade()
    {
        Task<char> grade = new Task<char>(GetLetterGrade);

        return grade;
    }

    private async Task<Semester> GradeReport()
    {
        var summary = await GetCourseGrade();

        Student pupil = new Student()
        {
            StudentNumber = 939485,
            LetterGrade = summary
        };

        return null;
    }
}

public class Student
{
    public long StudentNumber { get; set; }
    public char LetterGrade   { get; set; }
}

public class Semester
{
    public int Course1 { get; set; }
    public int Course2 { get; set; }
    public int Course3 { get; set; }
    public int Course4 { get; set; }
    public int Course5 { get; set; }
}

As always, if you are not planning to use the value many times, you don't have to first declare a variable. You can call the method where it is needed. Here is an example:

private async Task<Semester> GradeReport()
{
    Student pupil = new Student()
    {
        StudentNumber = 939485,
        LetterGrade = await GetCourseGrade()
    };

    return null;
}

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2014-2019, FunctionX Home