我发现你的程序有几个问题。
- 虽然
Preform
既不是异步也不是事件处理程序,它不返回任务
- 任务开始于
Preform
在完成 Preform 之前不会等待。因此你永远不知道它们什么时候完成,也不知道结果是什么(例外?)。您甚至可以在程序完成之前结束它们
- 启动任务后,无法保证它何时运行。如果您等待任务,您只能确定语句已经执行。
- 使用 async-await 是一种确保您的线程四处查看是否可以做有用的事情的方法,而不是在必须等待某些事情时无所事事地等待。
Thread.Sleep
是忙碌的等待。如果您想环顾四周看看是否可以做其他事情,请使用await Task.Delay(TimeSpan.FromSeconds(1))
反而。
就您而言,在等待应该写入您的行的过程之前,您无法确定是否已写入任何控制台行。如果您在等待第一个任务之前启动第二个任务,则您不知道第一个任务已经进行了多远,因此您无法确定文本是否已写入控制台。
C# 7.1 引入了异步任务 Main() https://www.c-sharpcorner.com/article/working-with-async-main-in-c-sharp-7-1/,所以你可以用它来代替传统的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();
}
为了完整性:其他功能
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");
}
因为等待在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);
}