Ros*_*han 5 c# asynchronous async-await
我有四种方法。
以下是我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncObservation
{
class Program
{
static void Main(string[] args)
{
preform();
}
public static async Task Working()
{
Console.WriteLine("Please wait, the program is running");
}
public static async Task Takingtime()
{
Console.WriteLine("This Program started");
Thread.Sleep(1000);
Console.WriteLine("The Program finished");
}
public static async void preform()
{
Task timer = Takingtime();
Task wait = Working();
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后:我需要显示
This program started.
Please wait, the program is running
The program ended.
Run Code Online (Sandbox Code Playgroud)
我发现你的程序有几个问题。
Preform既不是异步也不是事件处理程序,但它不返回任务Preform在完成 Preform 之前,不会等待开始的任务。因此你永远不知道它们什么时候完成,也不知道结果是什么(例外?)。您甚至可以在程序完成之前结束它们Thread.Sleep是忙碌的等待。如果您想环顾四周看看是否可以做其他事情,请使用await Task.Delay(TimeSpan.FromSeconds(1))。就您而言,在等待应该写入您的行的过程之前,您无法确定是否已写入任何控制台行。如果您在等待第一个任务之前启动第二个任务,则您不知道第一个任务已经进行了多远,因此您无法确定文本是否已写入控制台。
C# 7.1 引入了 async Task Main(),因此您可以使用它来代替传统的void Main. 它使您无需捕获和解释AggregateException您开始使流程异步的任务所引发的问题。
如果您不想使用async Main,您当然可以使用Task.Run来调用异步函数:
static void Main(string[] args)
{
try
{
var preformTask = Task.Run( () => Preform() );
DoSomethingElse(); // if needed
preformTask.Wait(); // wait for preformTask to finish
Console.WriteLine("Task completed; press any key to finish");
Console.ReadKey();
}
catch (Exception exc) // inclusive ggregateException if one of your Task fails
{
ProcessException(exc)
}
}
static async Task preform()
{
// To be certain that the Console Line has been written: await
await Takingtime();
// if here, you are certain that the Line has been written,
// or course you have lost parallel processing
await Working();
}
Run Code Online (Sandbox Code Playgroud)
为了完整性:其他功能
public static async Task Working()
{
Console.WriteLine("Please wait, the program is running");
// either return a completed Task, or await for it (there is a difference!
await Task.CompletedTask;
// or:
return Task.CompletedTask; // do not declare async in this case
}
public static async Task Takingtime()
{
Console.WriteLine("This Program started");
//Use Task.Delay instead of Sleep
await Task.Delay(TimeSpan.FromSeconds(1); // improved readability
Console.WriteLine("The Program finished");
}
Run Code Online (Sandbox Code Playgroud)
因为Preform你在等待,所以确信文本已经写好了。但是,您失去了一些并行性。
如果您确实希望同时执行这些过程,则无法确定何时写入文本。如果这很重要,则将应首先运行的部分(写入控制台)与应并行运行的部分(Task.Delay)分开
static async Task preform()
{
// Do the things that should be done before parallel tasks are run
await DoThisFirst();
// start the Tasks that can work parallel: not sure what statements are executed first
var taskA = DoTaskA();
var taskB = DoTaskB();
// if here, you are free to do something else
// can't be sure about the status of taskA nor taskB
DoSomethingElse();
// if you want to do something after you know that the tasks have completed:
// await the tasks here:
await Task.When (new Task[] {taskA, taskB});
// if here, you are certain that all parallel tasks have completed successfully
// if desired fetch the return values of the Tasks:
var returnValueA = taskA.Result;
var returnValueB = taskB.Result;
// do all async things of which you needed to be certain that both tasks finished
// for example:
await ProcessResults(returnValueA, returnValueB);
}
Run Code Online (Sandbox Code Playgroud)
在控制台应用程序中,可以.Wait()在void Main方法中使用调用。
在某些需要同步的上下文中,.Wait()可能会导致死锁(ASP.NET 有一个同步请求,或者具有 UI 线程的 XAML/WinForms),但这里没有任何同步内容。
static void Main()
{
preform.Wait()
}
Run Code Online (Sandbox Code Playgroud)
这将等待异步工作同步完成。您需要该方法同步运行,以便它不会提前返回。如果使用async voidandawait方法会立即返回并退出该方法,在方法await中不起作用Main。
我还建议使用await Task.Delay(1000);而不是Thread.Sleep(1000);因为这是async闲置的规范方式。
对于您的代码示例:
class Program
{
static void Main(string[] args)
{
preform().Wait();
Console.ReadLine();
}
public static async Task Working()
{
Console.WriteLine("Please wait, the program is running");
}
public static async Task Takingtime()
{
Console.WriteLine("This Program started");
await Task.Delay(1000);
Console.WriteLine("The Program finished");
}
public static Task preform()
{
return Task.WhenAll(
Takingtime(),
Working());
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12753 次 |
| 最近记录: |