狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

[轉(zhuǎn)帖]C# Task詳解

freeflydom
2023年5月20日 12:1 本文熱度 1504

1、Task產(chǎn)生背景

Task出現(xiàn)之前,微軟的多線程處理方式有:Thread→ThreadPool→委托的異步調(diào)用,雖然也可以基本業(yè)務需要的多線程場景,但它們在多個線程的等待處理方面、資源占用方面、線程延續(xù)和阻塞方面、線程的取消方面等都顯得比較笨拙,在面對復雜的業(yè)務場景下,顯得有點捉襟見肘了。

ThreadPool相比Thread來說具備了很多優(yōu)勢,但是ThreadPool卻又存在一些使用上的不方便。比如:

  • ThreadPool不支持線程的取消、完成、失敗通知等交互性操作;

  • ThreadPool不支持線程執(zhí)行的先后次序;

正是在這種背景下,Task應運而生。Task是微軟在.Net 4.0時代推出來的,也是微軟極力推薦的一種多線程的處理方式,Task看起來像一個Thread,實際上,它是在ThreadPool的基礎(chǔ)上進行的封裝,Task的控制和擴展性很強,在線程的延續(xù)、阻塞、取消、超時等方面遠勝于ThreadThreadPool。以下是一個簡單的任務示例:

static void Main(string[] args)
{
    Task t = new Task(() =>
    {
        Console.WriteLine("任務開始工作……");
        Thread.Sleep(5000);  //模擬工作過程
    });
    t.Start();
    t.ContinueWith(task =>
    {
        Console.WriteLine("任務完成,完成時候的狀態(tài)為:");
        Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", 
                          task.IsCanceled, task.IsCompleted, task.IsFaulted);
    });
    Console.ReadKey();
}

2、Task使用方法

2.1 創(chuàng)建和啟動任務

2.1.1 無返回值的方式

方式1:調(diào)用Start方法
var t1 = new Task(() => TaskMethod("Task 1"));
t1.Start();
Task.WaitAll(t1);//等待所有任務結(jié)束

任務的狀態(tài):Start之前為created,之后為WaitingToRun

方式2:靜態(tài)方法Run
Task.Run(() => TaskMethod("Task 2"));
方式3:TaskFactory工廠
// 方法1. TaskFactory工廠
TaskFactory taskFactory = new TaskFactory() ;
taskFactory.StartNew(() => TaskMethod("Task 3"));
// 方法2. Task.Factory屬性
Task.Factory.StartNew(() => TaskMethod("Task 3"));
//或者
var t3=Task.Factory.StartNew(() => TaskMethod("Task 3"));
Task.WaitAll(t3);

任務的狀態(tài):Start之前為Running,之后為Running

static void Main(string[] args)
{
    var t1 = new Task(() => TaskMethod("Task 1"));
    var t2 = new Task(() => TaskMethod("Task 2"));
    t2.Start();
    t1.Start();
    Task.WaitAll(t1, t2);
    Task.Run(() => TaskMethod("Task 3"));
    Task.Factory.StartNew(() => TaskMethod("Task 4"));
    //標記為長時間運行任務,則任務不會使用線程池,而在單獨的線程中運行。
    Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning);
    
    #region 常規(guī)的使用方式
    Console.WriteLine("主線程執(zhí)行業(yè)務處理.");
    //創(chuàng)建任務
    Task task = new Task(() =>
                         {
                             Console.WriteLine("使用`System.Threading.Tasks.Task`執(zhí)行異步操作.");
                             for (int i = 0; i < 10; i++)
                             {
                                 Console.WriteLine(i);
                             }
                         });
    //啟動任務,并安排到當前任務隊列線程中執(zhí)行任務(System.Threading.Tasks.TaskScheduler)
    task.Start();
    Console.WriteLine("主線程執(zhí)行其他處理");
    task.Wait();
    #endregion
    Thread.Sleep(TimeSpan.fromSeconds(1));
    Console.ReadLine();
}
static void TaskMethod(string name)
{
    Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                      name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
}
方式4:RunSynchronously同步啟動

Task實例化后調(diào)用同步方法RunSynchronously,進行線程啟動。(PS: 類似委托開啟線程,BeginInvoke是異步,而Invoke是同步)

var task = new Task(() => TaskMethod("Task 1"));
task.RunSynchronously();
async/await的實現(xiàn)方式
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
    class Program
    {
        async static void AsyncFunction()
        {
            await Task.Delay(1);
            Console.WriteLine("使用`System.Threading.Tasks.Task`執(zhí)行異步操作.");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(string.Format("AsyncFunction:i={0}", i));
            }
        }
        public static void Main()
        {
            Console.WriteLine("主線程執(zhí)行業(yè)務處理.");
            AsyncFunction();
            Console.WriteLine("主線程執(zhí)行其他處理");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(string.Format("Main:i={0}", i));
            }
            Console.ReadLine();
        }
    }
}

2.1.2 帶返回值的方式

方式4:
Task<int> task = createTask("Task 1");
task.Start(); 
int result = task.Result;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
    class Program
    {
        static Task<int> createTask(string name)
        {
            return new Task<int>(() => TaskMethod(name));
        }
        static void Main(string[] args)
        {
            TaskMethod("Main Thread Task");
            Task<int> task = createTask("Task 1");
            task.Start();
            int result = task.Result;
            Console.WriteLine("Task 1 Result is: {0}", result);
            task = createTask("Task 2"); 
            task.RunSynchronously(); //該任務會運行在主線程中
            result = task.Result;
            Console.WriteLine("Task 2 Result is: {0}", result);
            task = createTask("Task 3");
            Console.WriteLine(task.Status);
            task.Start();
            while (!task.IsCompleted)
            {
                Console.WriteLine(task.Status);
                Thread.Sleep(TimeSpan.fromSeconds(0.5));
            }
            Console.WriteLine(task.Status);
            result = task.Result;
            Console.WriteLine("Task 3 Result is: {0}", result);
            #region 常規(guī)使用方式
            //創(chuàng)建任務
            Task<int> getsumtask = new Task<int>(() => Getsum());
            //啟動任務,并安排到當前任務隊列線程中執(zhí)行任務(System.Threading.Tasks.TaskScheduler)
            getsumtask.Start();
            Console.WriteLine("主線程執(zhí)行其他處理");
            getsumtask.Wait(); //等待任務的完成執(zhí)行過程
            Console.WriteLine("任務執(zhí)行結(jié)果:{0}", getsumtask.Result.ToString());//獲得任務的執(zhí)行結(jié)果
            #endregion
        }
        static int TaskMethod(string name)
        {
            Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
                name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
            Thread.Sleep(TimeSpan.fromSeconds(2));
            return 42;
        }
        static int Getsum()
        {
            int sum = 0;
            Console.WriteLine("使用`Task`執(zhí)行異步操作.");
            for (int i = 0; i < 100; i++)
            {
                sum += i;
            }
            return sum;
        }
    }
}
using System;
using System.Threading.Tasks;
namespace ConsoleApp1
{
    class Program
    {
        public static void Main()
        {
            var ret1 = AsyncGetsum();
            Console.WriteLine("主線程執(zhí)行其他處理");
            for (int i = 1; i <= 3; i++)
                Console.WriteLine("Call Main()");
            int result = ret1.Result;     //阻塞主線程
            Console.WriteLine("任務執(zhí)行結(jié)果:{0}", result);
        }
        async static Task<int> AsyncGetsum()
        {
            await Task.Delay(1);
            int sum = 0;
            Console.WriteLine("使用`Task`執(zhí)行異步操作.");
            for (int i = 0; i < 100; i++)
            {
                sum += i;
            }
            return sum;
        }
    }
}

2.2 線程等待、延續(xù)和組合

2.2.1 Task的線程等待和延續(xù)主要以下幾類:

  • Wait:針對單個Task的實例,可以task1.wait進行線程等待

  • WaitAny:線程列表中任何一個線程執(zhí)行完畢即可執(zhí)行(阻塞主線程)

  • WaitAll:線程列表中所有線程執(zhí)行完畢方可執(zhí)行(阻塞主線程)

  • WhenAny:與ContinueWith配合,線程列表中任何一個執(zhí)行完畢,則繼續(xù)ContinueWith中的任務(開啟新線程,不阻塞主線程)

  • WhenAll:與ContinueWith配合,線程列表中所有線程執(zhí)行完畢,則繼續(xù)ContinueWith中的任務(開啟新線程,不阻塞主線程)

  • ContinueWith:與WhenAny或WhenAll配合使用

  • ContinueWhenAny:等價于Task的WhenAny+ContinueWith

  • ContinueWhenAll:等價于Task的WhenAll+ContinueWith

public static void Main()
{
    //創(chuàng)建一個任務
    Task<int> task = new Task<int>(() =>
    {
        int sum = 0;
        Console.WriteLine("使用`Task`執(zhí)行異步操作.");
        for (int i = 0; i < 100; i++)
        {
            sum += i;
        }
        return sum;
    });
    //啟動任務,并安排到當前任務隊列線程中執(zhí)行任務(System.Threading.Tasks.TaskScheduler)
    task.Start();
    Console.WriteLine("主線程執(zhí)行其他處理");
    //任務完成時執(zhí)行處理。
    Task cwt = task.ContinueWith(t =>
    {
        Console.WriteLine("任務完成后的執(zhí)行結(jié)果:{0}", t.Result.ToString());
    });
    task.Wait();
    cwt.Wait();
    
    Action<string,int> log = (name,time) =>
    {
        Console.WriteLine($"{name}任務開始...");
        Thread.Sleep(time);
        Console.WriteLine($"{name}任務結(jié)束!");
    };
    List<Task> tasks = new List<Task>
    {
        Task.Run(() => log("張三",3000)),
        Task.Run(() => log("李四",1000)),
        Task.Run(() => log("王五",2000))
    };
    //以下語句逐個測試效果
    Task.WaitAny(tasks.ToArray());
    Task.WaitAll(tasks.ToArray());
    Task.WhenAny(tasks.ToArray()).ContinueWith(x => Console.WriteLine("某個Task執(zhí)行完畢"));
    Task.WhenAll(tasks.ToArray()).ContinueWith(x => Console.WriteLine("所有Task執(zhí)行完畢"));
    Task.Factory.ContinueWhenAny(tasks.ToArray(), x => Console.WriteLine("某個Task執(zhí)行完畢"));
    Task.Factory.ContinueWhenAll(tasks.ToArray(), x => Console.WriteLine("所有Task執(zhí)行完畢"));
    Console.Read();
}

2.2.2 任務的串行

static void Main(string[] args)
{
    ConcurrentStack<int> stack = new ConcurrentStack<int>();
    //t1先串行
    var t1 = Task.Factory.StartNew(() =>
    {
        stack.Push(1);
        stack.Push(2);
    });
    //t2,t3并行執(zhí)行
    var t2 = t1.ContinueWith(t =>
    {
        int result;
        stack.TryPop(out result);
        Console.WriteLine("Task t2 result={0},Thread id {1}", result, Thread.CurrentThread.ManagedThreadId);
    });
    //t2,t3并行執(zhí)行
    var t3 = t1.ContinueWith(t =>
    {
        int result;
        stack.TryPop(out result);
        Console.WriteLine("Task t3 result={0},Thread id {1}", result, Thread.CurrentThread.ManagedThreadId);
    });
    //等待t2和t3執(zhí)行完
    Task.WaitAll(t2, t3);
    //t4串行執(zhí)行
    var t4 = Task.Factory.StartNew(() =>
    {
        Console.WriteLine("當前集合元素個數(shù):{0},Thread id {1}", stack.Count, Thread.CurrentThread.ManagedThreadId);
    });
    t4.Wait();
}

2.2.3 子任務

public static void Main()
{
    Task<string[]> parent = new Task<string[]>(state =>
    {
        Console.WriteLine(state);
        string[] result = new string[2];
        //創(chuàng)建并啟動子任務
        new Task(() => { result[0] = "我是子任務1"; }, TaskCreationOptions.AttachedToParent).Start();
        new Task(() => { result[1] = "我是子任務2"; }, TaskCreationOptions.AttachedToParent).Start();
        return result;
    }, "我是父任務,并在我的處理過程中創(chuàng)建多個子任務,所有子任務完成以后我才會結(jié)束執(zhí)行");
    //任務完成后執(zhí)行
    parent.ContinueWith(t =>
    {
        Array.ForEach(t.Result, r => Console.WriteLine(r));
    });    
    parent.Start(); //啟動父任務
    parent.Wait();//等待任務結(jié)束Wait只能等待父線程結(jié)束,沒辦法等到父線程的ContinueWith結(jié)束
    Console.ReadLine();
}

2.2.4 動態(tài)并行

TaskCreationOptions.AttachedToParent父任務等待所有子任務完成后整個任務才算完成

class Node
{
    public Node Left { get; set; }
    public Node Right { get; set; }
    public string Text { get; set; }
}
class Program
{
    static Node GetNode()
    {
        Node root = new Node
        {
            Left = new Node
            {
                Left = new Node{ Text = "L-L" },
                Right = new Node{ Text = "L-R" },
                Text = "L"
            },
            Right = new Node
            {
                Left = new Node{ Text = "R-L" },
                Right = new Node{ Text = "R-R" },
                Text = "R"
            },
            Text = "Root"
        };
        return root;
    }
    static void Main(string[] args)
    {
        Node root = GetNode();
        DisplayTree(root);
    }
    static void DisplayTree(Node root)
    {
        var task = Task.Factory.StartNew(() => DisplayNode(root),
                                        CancellationToken.None,
                                        TaskCreationOptions.None,
                                        TaskScheduler.Default);
        task.Wait();
    }
    static void DisplayNode(Node current)
    {
        if (current.Left != null)
            Task.Factory.StartNew(() => DisplayNode(current.Left),
                                        CancellationToken.None,
                                        TaskCreationOptions.AttachedToParent,
                                        TaskScheduler.Default);
        if (current.Right != null)
            Task.Factory.StartNew(() => DisplayNode(current.Right),
                                        CancellationToken.None,
                                        TaskCreationOptions.AttachedToParent,
                                        TaskScheduler.Default);
        Console.WriteLine("當前節(jié)點的值為{0};處理的ThreadId={1}", current.Text, Thread.CurrentThread.ManagedThreadId);
    }
}

2.3 取消任務

private static int TaskMethod(string name, int seconds, CancellationToken token)
{
    Console.WriteLine("Task {0} 正在運行,當前線程id {1}. Is thread pool thread: {2}",
        name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    for (int i = 0; i < seconds; i++)
    {
        Thread.Sleep(TimeSpan.fromSeconds(1));
        if (token.IsCancellationRequested) return -1;
    }
    return 42 * seconds;
}
private static void Main(string[] args)
{
    var cts = new CancellationTokenSource();
    var longTask = new Task<int>(() => TaskMethod("Task 1", 10, cts.Token), cts.Token);
    Console.WriteLine(longTask.Status);
    cts.Cancel();
    Console.WriteLine(longTask.Status);
    Console.WriteLine("第一個任務在執(zhí)行前已被取消");
    cts = new CancellationTokenSource();
    longTask = new Task<int>(() => TaskMethod("Task 2", 10, cts.Token), cts.Token);
    longTask.Start();
    for (int i = 0; i < 5; i++)
    {
        Thread.Sleep(TimeSpan.fromSeconds(0.5));
        Console.WriteLine(longTask.Status);
    }
    cts.Cancel();
    for (int i = 0; i < 5; i++)
    {
        Thread.Sleep(TimeSpan.fromSeconds(0.5));
        Console.WriteLine(longTask.Status);
    }
    Console.WriteLine("任務已完成,結(jié)果為 {0}.", longTask.Result);
}

2.4 處理異常

2.4.1 單個任務

static int TaskMethod(string name, int seconds)
{
    Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
        name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    Thread.Sleep(TimeSpan.fromSeconds(seconds));
    throw new Exception("Boom!");
    return 42 * seconds;
}
static void Main(string[] args)
{
    try
    {
        Task<int> task = Task.Run(() => TaskMethod("Task 2", 2));
        int result = task.GetAwaiter().GetResult();
        Console.WriteLine("Result: {0}", result);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Task 2 Exception caught: {0}", ex.Message);
    }
    Console.WriteLine("----------------------------------------------");
    Console.ReadLine();
}

2.4.2 多個任務

static int TaskMethod(string name, int seconds)
{
    Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
        name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    Thread.Sleep(TimeSpan.fromSeconds(seconds));
    throw new Exception(string.Format("Task {0} Boom!", name));
    return 42 * seconds;
}
public static void Main(string[] args)
{
    try
    {
        var t1 = new Task<int>(() => TaskMethod("Task 3", 3));
        var t2 = new Task<int>(() => TaskMethod("Task 4", 2));
        var complexTask = Task.WhenAll(t1, t2);
        var exceptionHandler = complexTask.ContinueWith(t =>
                Console.WriteLine("Result: {0}", t.Result),
                TaskContinuationOptions.OnlyOnFaulted
            );
        t1.Start();
        t2.Start();
        Task.WaitAll(t1, t2);
    }
    catch (AggregateException ex)
    {
        ex.Handle(exception =>
        {
            Console.WriteLine(exception.Message);
            return true;
        });
    }
}

2.4.3 async/await的方式

class Program
{
    static async Task ThrowNotImplementedExceptionAsync()
    {
        throw new NotImplementedException();
    }
    static async Task ThrowInvalidOperationExceptionAsync()
    {
        throw new InvalidOperationException();
    }
    static async Task Normal()
    {
        await Fun();
    }
    static Task Fun()
    {
        return Task.Run(() =>
        {
            for (int i = 1; i <= 10; i++)
            {
                Console.WriteLine("i={0}", i);
                Thread.Sleep(200);
            }
        });
    }
    static async Task ObserveOneExceptionAsync()
    {
        var task1 = ThrowNotImplementedExceptionAsync();
        var task2 = ThrowInvalidOperationExceptionAsync();
        var task3 = Normal();
        try
        {
            Task allTasks = Task.WhenAll(task1, task2, task3); //異步的方式
            await allTasks;
            //Task.WaitAll(task1, task2, task3); //同步的方式
        }
        catch (NotImplementedException ex)
        {
            Console.WriteLine("task1 任務報錯!");
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine("task2 任務報錯!");
        }
        catch (Exception ex)
        {
            Console.WriteLine("任務報錯!");
        }
    }
    public static void Main()
    {
        Task task = ObserveOneExceptionAsync();
        Console.WriteLine("主線程繼續(xù)運行........");
        task.Wait();
    }
}

2.5 Task.fromResult

此方法創(chuàng)建一個Task<TResult>對象,該對象的Task<TResult>.Result屬性為result,其Status屬性為RanToCompletion。 當立即知道任務的返回值而不執(zhí)行更長的代碼路徑時,通常使用方法。

class Program
{
    static IDictionary<string, string> cache = new Dictionary<string, string>()
    {
        {"0001","A"}, {"0002","B"}, {"0003","C"},
        {"0004","D"}, {"0005","E"}, {"0006","F"}
    };
    public static void Main()
    {
        Task<string> task = GetValuefromCache("0006");
        Console.WriteLine("主程序繼續(xù)執(zhí)行。。。。");
        string result = task.Result;
        Console.WriteLine("result={0}", result);
    }
    private static Task<string> GetValuefromCache(string key)
    {
        Console.WriteLine("GetValuefromCache開始執(zhí)行。。。。");
        string result = string.Empty;
        //Task.Delay(5000);
        Thread.Sleep(5000);
        Console.WriteLine("GetValuefromCache繼續(xù)執(zhí)行。。。。");
        if (cache.TryGetValue(key, out result))
        {
            return Task.fromResult(result);
        }
        return Task.fromResult("");
    }
}

2.6 Factory.fromAsync

APM模式(委托)轉(zhuǎn)換為任務,BeginXXXEndXXX

2.6.1 帶回調(diào)方式的

class Program
{
    private delegate string AsynchronousTask(string threadName);
    private static string Test(string threadName)
    {
        Console.WriteLine("開始...");
        Console.WriteLine("線程池是線程嗎: {0}", Thread.CurrentThread.IsThreadPoolThread);
        Thread.Sleep(TimeSpan.fromSeconds(2));
        Thread.CurrentThread.Name = threadName;
        return string.Format("線程名稱: {0}", Thread.CurrentThread.Name);
    }
    private static void Callback(IAsyncResult ar)
    {
        Console.WriteLine("開始一個回調(diào)...");
        Console.WriteLine("傳遞給callbak的狀態(tài): {0}", ar.AsyncState);
        Console.WriteLine("線程池是線程嗎: {0}", Thread.CurrentThread.IsThreadPoolThread);
        Console.WriteLine("線程池工作線程id: {0}", Thread.CurrentThread.ManagedThreadId);
    }
    //執(zhí)行的流程是:先執(zhí)行Test--->Callback--->task.ContinueWith
    static void Main(string[] args)
    {
        AsynchronousTask d = Test;
        Console.WriteLine("Option 1");
        Task<string> task = Task<string>.Factory.fromAsync(
            d.BeginInvoke("AsyncTaskThread", Callback, "委托異步調(diào)用"), d.EndInvoke);
        task.ContinueWith(t => Console.WriteLine("完成回調(diào), 現(xiàn)在繼續(xù)! Result: {0}", t.Result));
        while (!task.IsCompleted)
        {
            Console.WriteLine(task.Status);
            Thread.Sleep(TimeSpan.fromSeconds(0.5));
        }
        Console.WriteLine(task.Status);
    }
}

2.6.2 不帶回調(diào)方式的

class Program
{
    private delegate string AsynchronousTask(string threadName);
    private static string Test(string threadName)
    {
        Console.WriteLine("開始...");
        Console.WriteLine("線程池是線程嗎: {0}", Thread.CurrentThread.IsThreadPoolThread);
        Thread.Sleep(TimeSpan.fromSeconds(2));
        Thread.CurrentThread.Name = threadName;
        return string.Format("線程名稱: {0}", Thread.CurrentThread.Name);
    }
    //執(zhí)行的流程是:先執(zhí)行Test--->task.ContinueWith
    static void Main(string[] args)
    {
        AsynchronousTask d = Test;
        Task<string> task = Task<string>.Factory.fromAsync(
            d.BeginInvoke, d.EndInvoke, "AsyncTaskThread", "委托異步調(diào)用");
        task.ContinueWith(t => Console.WriteLine("任務完成,現(xiàn)在運行一個延續(xù)! Result: {0}", t.Result));
        while (!task.IsCompleted)
        {
            Console.WriteLine(task.Status);
            Thread.Sleep(TimeSpan.fromSeconds(0.5));
        }
        Console.WriteLine(task.Status);
    }
}

2.6.3 Task啟動帶參數(shù)和返回值的函數(shù)任務

方法1
private int MyTest(object i)
{
    this.Invoke(new Action(() =>
    {
        pictureBox1.Visible = true;
    }));
    System.Threading.Thread.Sleep(3000);
    MessageBox.Show("hello:" + i);
    this.Invoke(new Action(() =>
    {
        pictureBox1.Visible = false;
    }));
    return 0;
}
private void Call()
{
    //Func<string, string> funcOne = delegate(string s){ return "fff"; };
    object i = 55;
    var t = Task<int>.Factory.StartNew(new Func<object, int>(MyTest), i);
}
方法2
private async Task<int> MyTest(object i)
{
    this.Invoke(new Action(() =>
    {
        pictureBox1.Visible = true;
    }));
    HttpClient client = new HttpClient();
    var a = await client.GetAsync("http://www.baidu.com");
    Task<string> s = a.Content.ReadAsStringAsync();
    MessageBox.Show (s.Result);
    this.Invoke(new Action(() =>
    {
        pictureBox1.Visible = false;
    }));
    return 0;
}
async private void Call()
{
    object i = 55;
    var t = Task<Task<int>>.Factory.StartNew(new Func<object, Task<int>>(MyTest), i);
}
方法3
private async void MyTest()
{
    this.Invoke(new Action(() =>
    {
        pictureBox1.Visible = true;
    }));
    HttpClient client = new HttpClient();
    var a = await client.GetAsync("http://www.baidu.com");
    Task<string> s = a.Content.ReadAsStringAsync();
    MessageBox.Show (s.Result);
    this.Invoke(new Action(() =>
    {
        pictureBox1.Visible = false;
    }));
}
private void Call()
{
    var t = Task.Run(new Action(MyTest));
    //相當于
    //Thread th= new Thread(new ThreadStart(MyTest));
    //th.Start();
}

2.7 使用IProgress

IProgress<in T>只提供了一個方法void Report(T value),通過Report方法把一個T類型的值報告給IProgress,然后IProgress<in T>的實現(xiàn)類Progress<in T>的構(gòu)造函數(shù)接收類型為Action<T>的形參,通過這個委托讓進度顯示在UI界面中。

class Program
{
    static void DoProcessing(IProgress<int> progress)
    {
        for (int i = 0; i <= 100; ++i)
        {
            Thread.Sleep(100);
            if (progress != null)
            {
                progress.Report(i);
            }
        }
    }
    static async Task Display()
    {
        //當前線程
        var progress = new Progress<int>(percent =>
        {
            Console.Clear();
            Console.Write("{0}%", percent);
        });
        //線程池線程
        await Task.Run(() => DoProcessing(progress));
        Console.WriteLine("");
        Console.WriteLine("結(jié)束");
    }
    public static void Main()
    {
        Task task = Display();
        task.Wait();
    }
}


---------------------------------

https://www.cnblogs.com/zhaoshujie/p/11082753.html


該文章在 2023/5/20 12:01:34 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務費用、相關(guān)報表等業(yè)務管理,結(jié)合碼頭的業(yè)務特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved