Task Parallel Library02. Further, parallellibrary02
In the previous article, I learned about the basic usage of tasks.
If a method returns a Task and a Task <T>, how does one obtain the return value of the Task, will the process of obtaining the Value block the thread?
static void Main(string[] args)
{
var result = DoWorkAsync().Result;
Console.WriteLine(result);
Console. WriteLine ("When will I display ");
Console.ReadKey();
}
static Task<string> DoWorkAsync()
{
return Task<string>.Factory.StartNew(() =>
{
Thread.Sleep(3000);
return "hello";
});
}
It can be seen that the Result attribute of a Task can obtain the returned value, and the thread in the process of obtaining the returned value is blocked.
Can I get the return value of a thread without blocking the thread? The ContinueWith method is executed after the end of a thread, but does not block the thread at the same time.
static void Main(string[] args)
{
DoWorkAsync().ContinueWith((pre) =>
{
Console.WriteLine(pre.Result);
});
Console. WriteLine ("When will I display ");
Console.ReadKey();
}
But ContinueWith will always run after a thread ends. can I control the process of ContinueWith?
static void Main(string[] args)
{
DoWorkAsync().ContinueWith((pre) =>
{
Console.WriteLine(pre.Result);
}, TaskContinuationOptions.NotOnFaulted);
DoWorkAsync().ContinueWith((pre) =>
{
Console.WriteLine(pre.Exception);
},TaskContinuationOptions.OnlyOnFaulted);
Console. WriteLine ("When will I display ");
Console.ReadKey();
}
If no error exists, the returned value is displayed. If an error exists, the error message is displayed.
You can also use the Task instance method IsCompleted to determine whether a thread is completed.
static void Main(string[] args)
{
var doWorkTask = DoWorkAsync();
if (doWorkTask.IsCompleted)
{
Console.WriteLine(doWorkTask.Result);
}
else
{
doWorkTask.ContinueWith((pre) =>
{
Console.WriteLine(pre.Result);
}, TaskContinuationOptions.NotOnFaulted);
doWorkTask.ContinueWith((pre) =>
{
Console.WriteLine(pre.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
}
Console. WriteLine ("When will I display ");
Console.ReadKey();
}
The Status attribute of the Task and the TaskStatus enumeration can be used to determine the Status of the Task.
static void Main(string[] args)
{
var httpClient = new HttpClient();
Task<string> baiduTask = httpClient.GetStringAsync("http://www.baidu.com");
var httpClient2 = new HttpClient();
Task<string> sinaTask = httpClient2.GetStringAsync("http://www.sina.com.cn");
// Wait until the preceding two tasks are completed.
Task<string[]> task = Task.WhenAll(baiduTask, sinaTask);
task.ContinueWith(stringArray =>
{
// If the task is completed
if (task.Status == TaskStatus.RanToCompletion)
{
for (int i = 0; i < stringArray.Result.Length;i++)
{
Console.WriteLine(stringArray.Result[i].Substring(0,100));
}
}
Else if (task. Status = TaskStatus. Canceled) // if Canceled
{
Console. WriteLine ("{0} this task has been canceled", task. Id );
}
Else // Error
{
Console. WriteLine ("error occurred ~~ ");
foreach (var item in task.Exception.InnerExceptions)
{
Console.WriteLine(item.Message);
}
}
});
Console.ReadKey();
}
To control the lifecycle of a Task, you can use TaskCompletionSource <T>.
static void Main(string[] args)
{
AsyncFactory.GetIntAsync().ContinueWith((prev) =>
{
if (prev.Status == TaskStatus.RanToCompletion)
{
Console.WriteLine(prev.Result);
}
else if (prev.Status == TaskStatus.Canceled)
{
Console. WriteLine ("task canceled ");
}
else
{
Console. WriteLine ("error occurred ");
Console.WriteLine(prev.Exception);
}
});
Console.ReadKey();
}
}
public static class AsyncFactory
{
public static Task<int> GetIntAsync()
{
var tsc = new TaskCompletionSource<int>();
var timer = new System.Timers.Timer(2000);
timer.AutoReset = false;
timer.Elapsed += (s, e) =>
{
tsc.SetResult(10);
timer.Dispose();
};
timer.Start();
return tsc.Task;
}
}
Above, the SetResult of TaskCompletionSource <T> is used to set the return value for the thread, and the. Task of TaskCompletionSource <T> gets the thread.
In addition, starting from. NET 4.5, the static method FromResult of the Task receives the T type and returns the Task <T>.
static void Main(string[] args)
{
var intTask = GetIntAsync();
if (intTask.Status == TaskStatus.RanToCompletion)
{
Console.WriteLine(intTask.Result);
}
else if (intTask.Status == TaskStatus.Canceled)
{
Console. WriteLine ("task canceled ");
}
else
{
Console. WriteLine ("error occurred ");
Console.WriteLine(intTask.Exception);
}
Console.ReadKey();
}
static Task<int> GetIntAsync()
{
return Task.FromResult(10);
}