C#异步操作的知识点一

  
#region 使用Task对象中的T返回异步方法里面的值,也可以是获取异步的状态。
    //class Program
    //{
    //    static void Main(string[] args)
    //    {
    //        Task value = DoAsyncStuff.CalculateSumAsync(5, 6);
    //        Console.WriteLine($"Value:{value.Result}");            
    //        Console.ReadLine();
    //    }
    //}
    //static class DoAsyncStuff
    //{
//    public static async Task<int> CalculateSumAsync(int a, int b)
//    {
/*后面的awiat 返回的值跟方法返回的值并没有任何联系。

 int a=10
int sum = await Task.Run(() => { return (a + b); });
return a;*/
//        int sum = await Task.Run(() => { return (a + b); });
//        return sum;
//return 并没有返回某个值,而是退了异步
//    }
//}
#endregion
#region Task是反馈异步的状态
//class Program
//{

//    static void Main(string[] args)
//    {
//        Task value = DoAsyncStuff.CalculateSumAsync(5, 6);
//        value.Wait();
//        Console.WriteLine("Async Stuff is done");
//        Console.ReadLine();
//    }
//}
//static class DoAsyncStuff
//{

//    public static async Task CalculateSumAsync(int a, int b)
//    {
//        int sum = await Task.Run(() => { return (a + b); });
//        Console.WriteLine($"Value:{sum}");
//    }
//}
#endregion
#region 异步无任何返回
//class program
//{
//    static void Main(string[] args)
//    {
//        DoAsyncStuff.CalculateSumAsync(5, 6);
//        Thread.Sleep(5000);
//        Console.WriteLine("program is exit");
//        Console.ReadLine();
//    }

//}
//static class DoAsyncStuff
//{

//    public static async void CalculateSumAsync(int a, int b)
//    {

//        int sum = await Task.Run(() => { return (a + b); });
//        Console.WriteLine($"Value:{sum}");
//    }
//}
#endregion

#region 取消异步操作
        /*1、CancellationToken 包含一个任务是否被取消的的消息;
        2、拥有CancellAtionToken 对象的任务需要定期检查令牌(Token)的状态。如果CancellAtionToken 对象的IsCancellationRequested为True,则任务需要停止并返回。
        3、CancellAtionToken 是不可逆的,也就是说IsCancellationRequested为True就不能取消了。
        4、CancellAtionTokenScoure对象的创建分配给不同任务CancellAtionToken的对象,任何持有CancellAtionTokenScoure都可以调用cancell方法。这将会使IsCancellationRequested                
        为TRUE;*/
class program
{
    static void Main(string[] args)
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        CancellationToken ct = cts.Token;

        Myclass cls = new Myclass();
        Task ts = cls.RunAsync(ct);
        Thread.Sleep(3000);
        cts.Cancel();
        ts.Wait();
        Console.WriteLine($" Was Cancelled:{ct.IsCancellationRequested} ");
        Console.ReadLine();
    }
}
class Myclass
{
    public async Task RunAsync(CancellationToken ct)
    {
        if (ct.IsCancellationRequested)
        {
            return;
        }
        await Task.Run(() => { CycleMethod(ct); });
    }

    void CycleMethod(CancellationToken ct)
    {
        Console.WriteLine("starting CycleMethod;");
        const int max = 5;
        for (int i = 1; i <= max; i++)
        {
            if (ct.IsCancellationRequested)
            {
                return;
            }
            Thread.Sleep(1000);
            Console.WriteLine($" {i} of {max} interations completed");
        }
    }
}
#endregion
#region 异步的异常处理
class program
{
    static void Main(string[] args)
    {
        Task ts =  BadAnysc();
        ts.Wait();
        Console.WriteLine($"Task status :{ts.Status}");
        Console.WriteLine($"Task status :{ts.IsFaulted}");
        Console.ReadLine();

    }
    //异步操作异常
    static async Task BadAnysc()
    {
        try
        {
           await Task.Run(() => { throw new Exception("异常");});
        }
        catch 
        {

            Console.WriteLine("Exception in BadAsync.");
        }
    }


}
#endregion

//waitAll()方法 等待所有的异步执行完成,都有4重重载。

//waitAny()方法 等待某个异步执行完成,都有4重重载。

region whenAll 异步的等待所有相关的Task完成,不会占用主线程的事件。whenAny异步的等待相关某个的Task完成。await调用。

class program
{
    static void Main(string[] args)
    {

        MyDownLoadString dowmloadString = new MyDownLoadString();

        dowmloadString.DoRun();
        Console.ReadLine();

    }
}
class MyDownLoadString
{
    public void DoRun()
    {

        Task<int> task = CountCharactersAsync("http://www.baidu.com",
            "http://www.qq.com");
        Console.WriteLine("DoRun:t{0} Finished", task.IsCompleted ? "" : "NOT");
        Console.WriteLine("Result={0}", task.Result );


    }
    private async Task<int> CountCharactersAsync(string site1 ,string site2)
    {
        WebClient wc1 = new WebClient();
        WebClient wc2 = new WebClient();
        Task<string> t1 = wc1.DownloadStringTaskAsync(new Uri(site1));
        Task<string> t2 = wc2.DownloadStringTaskAsync(new Uri(site2));
        List<Task<string>> task1 = new List<Task<string>>();
        task1.Add(t1);
        task1.Add(t2);
        //await Task.WhenAll(task1);
        await Task.WhenAny(task1);
        Console.WriteLine("CCA:T1 {0 } Finished", t1.IsCompleted ? "" : "NOT");
        Console.WriteLine("CCA:T2 {0} Finished", t2.IsCompleted ? "" : "NOT");
        return t1.IsCompleted ? t1.Result.Length : t2.Result.Length;
    }
}
#endregion
#region Task.Dealy 暂停线程中的处理,Thread.Sleep会阻塞线程。
class program
{

    static void Main(string[] args)
    {
        Simple sm = new Simple();
        sm.DoRun();
        Console.ReadLine();
    }
}
class Simple
{
    Stopwatch sw = new Stopwatch();//用来确定应用程序运行的时间。
    private async void ShowDelayAsync()
    {
        sw.Start();
        Console.WriteLine("Before Delay:{0}", sw.ElapsedMilliseconds);
        await Task.Delay(5000);//暂停线程方法中的处理,不影响其他操作。
        //Thread.Sleep(5000);阻塞线程,线程不能进行其他操作
        Console.WriteLine("After Delay:{0}", sw.ElapsedMilliseconds);
    }
    public void DoRun()
    {
        Console.WriteLine("Caller:Before Call.");
        ShowDelayAsync();
        Console.WriteLine("Caller:After Call.");
    }
}
#endregion

posted @ 2022-02-10 17:32  跨界专家  阅读(33)  评论(0)    收藏  举报