久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C# 線程知識(shí)

 長江黃鶴 2014-01-07

      在C#4.0之前需要執(zhí)行一個(gè)復(fù)雜的異步操作時(shí),只能使用CLR線程池技術(shù)來執(zhí)行一個(gè)任務(wù),。線程池執(zhí)行異步任務(wù)時(shí),不知道任務(wù)何時(shí)完成,以及任務(wù)的在任務(wù)完成后不能獲取到返回值,。但是在C#4.0中引人了一個(gè)的任務(wù)(System.Threading.Tasks命名空間的類型)機(jī)制來解決異步操作完成時(shí)間和完成后返回值的問題。

1.使用Task類創(chuàng)建并執(zhí)行簡單任務(wù)

    通過使用Task的構(gòu)造函數(shù)來創(chuàng)建任務(wù),,并調(diào)用Start方法來啟動(dòng)任務(wù)并執(zhí)行異步操作,。創(chuàng)建任務(wù)時(shí),必須傳遞一個(gè)Action或Action<Object>類型的委托回調(diào)方法,,可以選擇的傳遞任務(wù)執(zhí)行時(shí)說需要的數(shù)據(jù)對象等,。Task類的構(gòu)造函數(shù)如下:

public Task(Action action);
public Task(Action<object> action, object state);
public Task(Action action, CancellationToken cancellationToken);
public Task(Action action, TaskCreationOptions creationOptions);
public Task(Action<object> action, object state, CancellationToken cancellationToken);
public Task(Action<object> action, object state, TaskCreationOptions creationOptions);
public Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions);
public Task(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions);

示例代碼:

static void Main(string[] args)

        {

            Console.WriteLine("主線程執(zhí)行業(yè)務(wù)處理.");

            //創(chuàng)建任務(wù)

            Task task = new Task(() =>{

                Console.WriteLine("使用System.Threading.Tasks.Task執(zhí)行異步操作.");

                for (int i = 0; i < 10; i++)

                {

                    Console.WriteLine(i);

                }

            });

            //啟動(dòng)任務(wù),并安排到當(dāng)前任務(wù)隊(duì)列線程中執(zhí)行任務(wù)(System.Threading.Tasks.TaskScheduler)

            task.Start();

            Console.WriteLine("主線程執(zhí)行其他處理");

            //主線程掛起1000毫秒,等待任務(wù)的完成,。

            Thread.Sleep(1000);

        }

任務(wù)調(diào)度結(jié)果:
image

2.等待任務(wù)的完成并獲取返回值

     使用任務(wù)執(zhí)行異步操作時(shí),,最主要的是要后的任務(wù)完成時(shí)的返回值。在任務(wù)類中有一個(gè)實(shí)例方法Wait(有許多重載版本)他能等待任務(wù)的完成,,我們也可以通過Task類的派生類Task<TResult>創(chuàng)建一個(gè)異步任務(wù),,并指定任務(wù)完成時(shí)返回值的類型,這樣可以通過Task<TResult>的實(shí)例對象獲取到任務(wù)完成后的返回值,。創(chuàng)建一個(gè)異步任務(wù)并執(zhí)行0到100求和操作返回最后的計(jì)算結(jié)果,,示例代碼:


static void TaskWait()
{
//創(chuàng)建任務(wù)
Task<int> task = new Task<int>(() =>
{
int sum = 0;
Console.WriteLine("使用Task執(zhí)行異步操作.");
for (int i = 0; i < 100; i++)
{
sum += i;
}
return sum;
});
//啟動(dòng)任務(wù),并安排到當(dāng)前任務(wù)隊(duì)列線程中執(zhí)行任務(wù)(System.Threading.Tasks.TaskScheduler)
task.Start();
Console.WriteLine("主線程執(zhí)行其他處理");
//等待任務(wù)的完成執(zhí)行過程。
task.Wait();
//獲得任務(wù)的執(zhí)行結(jié)果
Console.WriteLine("任務(wù)執(zhí)行結(jié)果:{0}", task.Result.ToString());
}

執(zhí)行結(jié)果:
image

Task類還有一些靜態(tài)方法,,WaitAll用于等待提供的所有 System.Threading.Tasks.Task 對象完成執(zhí)行過程和Wait用于等待提供的任一個(gè) System.Threading.Tasks.Task 對象完成執(zhí)行過程,,這兩個(gè)方法都有一些重載版本。

//等待所有任務(wù)完成  
public static void WaitAll(params Task[] tasks);
//等待任意一個(gè)任務(wù)完成
public static int WaitAny(params Task[] tasks);

3.使用ContinueWith方法在任務(wù)完成時(shí)啟動(dòng)一個(gè)新任務(wù)

     在使用能夠Task類的Wait方法等待一個(gè)任務(wù)時(shí)或派生類的Result屬性獲得任務(wù)執(zhí)行結(jié)果都有可能阻塞線程,,為了解決這個(gè)問題可以使用ContinueWith方法,,他能在一個(gè)任務(wù)完成時(shí)自動(dòng)啟動(dòng)一個(gè)新的任務(wù)來處理執(zhí)行結(jié)果。

示例代碼:

        static void TaskContinueWith()
        {
            //創(chuàng)建一個(gè)任務(wù)
            Task<int> task = new Task<int>(() =>
            {
            int sum = 0;
            Console.WriteLine("使用Task執(zhí)行異步操作.");
            for (int i = 0; i< 100; i++)
                {
                    sum += i;
                }
            return sum;
            });
            //啟動(dòng)任務(wù),并安排到當(dāng)前任務(wù)隊(duì)列線程中執(zhí)行任務(wù)(System.Threading.Tasks.TaskScheduler)
            task.Start();
            Console.WriteLine("主線程執(zhí)行其他處理");
            //任務(wù)完成時(shí)執(zhí)行處理,。
            Task cwt = task.ContinueWith(t => {
            Console.WriteLine("任務(wù)完成后的執(zhí)行結(jié)果:{0}", t.Result.ToString());
            });
            Thread.Sleep(1000);
        }

執(zhí)行結(jié)果:image

上述示例中任務(wù)不是等待完成來顯示執(zhí)行結(jié)果,,而是使用ContinueWith方法,它能夠知道任務(wù)在什么時(shí)候完成并啟動(dòng)一個(gè)新的任務(wù)來執(zhí)行任務(wù)完成后的處理。ContinueWith方法具有一些重載版本,,這些重載版本允許指定延續(xù)任務(wù)需要使用的數(shù)據(jù),、延續(xù)任務(wù)的工作方式(System.Threading.Tasks.TaskContinuationOptions的枚舉值按位OR運(yùn)行的結(jié)果)等。

4.創(chuàng)建父子任務(wù)和任務(wù)工廠的使用

    通過Task類創(chuàng)建的任務(wù)是頂級任務(wù),,可以通過使用 TaskCreationOptions.AttachedToParent 標(biāo)識(shí)把這些任務(wù)與創(chuàng)建他的任務(wù)相關(guān)聯(lián),,所有子任務(wù)全部完成以后父任務(wù)才會(huì)結(jié)束操作。示例如下:


static void ParentChildTask()
{
Task<string[]> parent = new Task<string[]>(state =>
{
Console.WriteLine(state);
string[] result = new string[2];
//創(chuàng)建并啟動(dòng)子任務(wù)
new Task(() => { result[0] = "我是子任務(wù)1,。"; }, TaskCreationOptions.AttachedToParent).Start();
new Task(() => { result[1] = "我是子任務(wù)2,。"; }, TaskCreationOptions.AttachedToParent).Start();
return result;
},"我是父任務(wù),并在我的處理過程中創(chuàng)建多個(gè)子任務(wù),,所有子任務(wù)完成以后我才會(huì)結(jié)束執(zhí)行,。");
//任務(wù)處理完成后執(zhí)行的操作
parent.ContinueWith(t =>
{
Array.ForEach(t.Result, r=>Console.WriteLine(r));
});
//啟動(dòng)父任務(wù)
parent.Start();
Console.Read();
}

執(zhí)行結(jié)果:
image

    如果需要?jiǎng)?chuàng)建一組具有相同狀態(tài)的任務(wù)時(shí),可以使用TaskFactory類或TaskFactory<TResult>類,。這兩個(gè)類創(chuàng)建一組任務(wù)時(shí)可以指定任務(wù)的CancellationToken,、TaskCreationOptions、TaskContinuationOptions和TaskScheduler默認(rèn)值,。

示例代碼:   

static void TaskFactoryApply()
{
Task parent = new Task(() =>
{
CancellationTokenSource cts = new CancellationTokenSource(5000);
//創(chuàng)建任務(wù)工廠
TaskFactory tf = new TaskFactory(cts.Token, TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
//添加一組具有相同狀態(tài)的子任務(wù)
Task[] task = new Task[]{
tf.StartNew(() => { Console.WriteLine("我是任務(wù)工廠里的第一個(gè)任務(wù),。"); }),
tf.StartNew(() => { Console.WriteLine("我是任務(wù)工廠里的第二個(gè)任務(wù)。"); }),
tf.StartNew(() => { Console.WriteLine("我是任務(wù)工廠里的第三個(gè)任務(wù),。"); })
};
});
parent.Start();
Console.Read();
}
}

執(zhí)行結(jié)果:
image

5.任務(wù)內(nèi)部實(shí)現(xiàn)和任務(wù)調(diào)度

    任務(wù)內(nèi)部有一組構(gòu)成任務(wù)狀態(tài)的屬性,,標(biāo)識(shí)任務(wù)的唯一Id、表示任務(wù)的執(zhí)行狀態(tài)(TaskStatus),、任務(wù)創(chuàng)建時(shí)提供的回調(diào)函數(shù)的引用和傳遞給回調(diào)函數(shù)的數(shù)據(jù)對象AsyncState,、對任務(wù)創(chuàng)建時(shí)的任務(wù)調(diào)度對象(TaskScheduler)的引用、對父任務(wù)的引用以及對執(zhí)行上下文的引用和ManualResetEventSlim對象的引用,。Task類和Task<TResult>類都實(shí)現(xiàn)了標(biāo)準(zhǔn)的釋放資源的接口,,允許在任務(wù)完成處理的時(shí)候使用Dispose方法釋放資源(關(guān)閉ManualResetEventSlim對象實(shí)例)??梢允褂肨ask類的CurrentId屬性獲得正在執(zhí)行的任務(wù)的Id,,如果沒有任務(wù)在執(zhí)行CurrentId返回值為null,CurrentId是一個(gè)int,?可空類型的屬性,。任務(wù)執(zhí)行的生命周期通過TaskStatus類型的一個(gè)值來表示,TaskStatus所包含的值:

        public enum TaskStatus
        { 
            Created = 0, 
            WaitingForActivation = 1, 
            WaitingToRun = 2, 
            Running = 3, 
            WaitingForChildrenToComplete = 4, 
            RanToCompletion = 5, 
            Canceled = 6, 
            Faulted = 7,
        }

      我們可以通過Task類的Exception屬性獲得任務(wù)在執(zhí)行過程中的所有異常,,Exception是一個(gè)AggregateException類型的屬性,。Task類提供了IsCanceled、IsCompleted,、IsFaulted屬性來獲得任務(wù)的完成狀態(tài),。通過ContinueWith,、ContinueWhenAll、ContinueWhenAny和FromAsync創(chuàng)建的后續(xù)任務(wù)都處于WaitingForActivation 狀態(tài),,這個(gè)狀態(tài)的任務(wù)會(huì)在父任務(wù)完成后自動(dòng)執(zhí)行,。

      在任務(wù)內(nèi)部由TaskScheduler類調(diào)度任務(wù)的執(zhí)行,該類是一個(gè)抽象類,,F(xiàn)CL中從他派生了兩個(gè)派生類:ThreadPoolTaskScheduler線程池任務(wù)調(diào)度器和SynchronizationContextTaskScheduler同步上下文任務(wù)調(diào)度器。所有任務(wù)默認(rèn)都是采用ThreadPoolTaskScheduler調(diào)度任務(wù),,他是采用線程池來執(zhí)行任務(wù),,可以通過TaskScheduler類的靜態(tài)屬性Default獲得對默認(rèn)任務(wù)調(diào)度器的引用。SynchronizationContextTaskScheduler任務(wù)調(diào)度器能夠用在Window form,、WPF等應(yīng)用程序,,他的任務(wù)調(diào)度是采用的GUI線程,所以他能同步更新UI組件,,可以通過TaskScheduler類的靜態(tài)方法FromCurrentSynchronizationContext獲得對一個(gè)同步上下文任務(wù)調(diào)度起的引用,。

任務(wù)調(diào)度示例:

        private void button1_Click(object sender, EventArgs e)
{
//獲得同步上下文任務(wù)調(diào)度器
TaskScheduler m_syncContextTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
//創(chuàng)建任務(wù),并采用默認(rèn)任務(wù)調(diào)度器(線程池任務(wù)調(diào)度器)執(zhí)行任務(wù)
Task<int> task = new Task<int>(() =>
{
//執(zhí)行復(fù)雜的計(jì)算任務(wù),。
Thread.Sleep(2000);
int sum = 0;
for (int i = 0; i< 100; i++)
{
sum += i;
}
return sum;
});
var cts = new CancellationTokenSource();
//任務(wù)完成時(shí)啟動(dòng)一個(gè)后續(xù)任務(wù),,并采用同步上下文任務(wù)調(diào)度器調(diào)度任務(wù)更新UI組件。
task.ContinueWith(t => { this.label1.Text = "采用SynchronizationContextTaskScheduler任務(wù)調(diào)度器更新UI,。/r/n計(jì)算結(jié)果是:" + task.Result.ToString(); },
cts.Token, TaskContinuationOptions.AttachedToParent, m_syncContextTaskScheduler);
task.Start();
}

執(zhí)行結(jié)果:image

    本文簡單的介紹了使用Task類來執(zhí)行異步操作以及任務(wù)的內(nèi)部實(shí)現(xiàn)與任務(wù)調(diào)度,。在執(zhí)行復(fù)雜異步操作時(shí),可以采用任務(wù)來執(zhí)行,,他能更好的知道異步操作在何時(shí)完成以及返回異步操作的執(zhí)行結(jié)果,。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多