Table of Contents

异步 Async

一个函数被标识了async,但是函数内部没使用await,实际上就是同步方法,但是会编译出async有关的东西,会浪费一些性能

总览

csharp异步操作.bmind

[待验证]如果程序的入口函数被标记为async,那么其返回值必须是Task,因为操作系统启动这个程序,就需要明确其结束时间,需要其是[可以等待的]

代码

using System.Threading;
 
class Application
{
    // 入口函数必须可以等待
    public static async Task Main()
    {
        System.Console.WriteLine("Main Start");
 
        var renderTask = RenderAsync();
        Console.WriteLine("Start Rendering");
 
        await renderTask;
 
        Console.WriteLine("Render Done");
 
        System.Console.WriteLine("Main Finish");
    }
 
    static async Task<List<float>> RenderAsync()
    {
        System.Action<float> drawProgress = (Value) =>
        {
            const int Length = 64;
 
            string Line = "\r[";
 
            for (int i = 0; i < Length; i += 1)
            {
                if (Length * Value > i) Line += "*";
                else Line += " ";
            }
 
            Line += "]";
 
            Console.Write(Line);
        };
 
        const int renderSize = 64;
 
        List<float> renderResult = new List<float>();
        List<Task<float>> renderTasks = new List<Task<float>>();
 
        for (int i = 0; i < renderSize; i += 1)
        {
            renderTasks.Add(Task.Run(() =>
            {
                return CastRay((uint)i);
            }));
        }
 
        // Wait a Single Task at one time
        while (renderTasks.Count > 0)
        {
            Task<float> finishedTask = await Task.WhenAny(renderTasks);
 
            // Save the Result Here
 
            renderTasks.Remove(finishedTask);
 
            drawProgress(1.0f - (1.0f * renderTasks.Count / renderSize));
        }
 
        // Wait All Tasks
        /*
        await Task.WhenAll(renderTasks);
 
        renderResult.Capacity = renderSize;
        for (int i = 0; i < renderSize; i += 1)
        {
            renderResult.Add(renderTasks[i].Result);
        }
        */
 
        drawProgress(1.0f);
        Console.WriteLine("");
 
        return renderResult;
    }
 
    // Real Compute
    static float CastRay(uint pixelIndex)
    {
        Thread.Sleep(1000);
 
        return (float)pixelIndex;
    }
}

外链资料

  1. 理解Task和async await https://www.cnblogs.com/ryzen/p/13938188.html 归档 (好文章)