对于以下代码(使用EdgeJS模块),我想在编写Start
之前等待异步方法sw.Elapsed
完成,我应该怎么做?
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using EdgeJs;
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
[STAThread]
static void Main()
{
// Application.EnableVisualStyles();
// Application.SetCompatibleTextRenderingDefault(false);
// Application.Run(new Form1());
Stopwatch sw =new Stopwatch();
sw.Start();
Task.Run((Action)Start).Wait();
//wait for start to complete --- how should I do it??
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
public static async void Start()
{
var func = Edge.Func(@"
var esprima = require('esprima');
var stringify = require('json-stable-stringify');
var esprimaast = esprima.parse('var a=1;', { loc: true });
var esprimaStr = stringify(esprimaast, { space: 3 });
return function (data, callback) {
callback(null, 'Node.js welcomes ' + esprimaStr);
}
");
Console.WriteLine(await func(".NET"));
//Console.WriteLine("hello");
}
}
答案 0 :(得分:4)
您不能等待async void
操作,除了异步事件处理程序之外,您都不应该使用async void
。
async void
有几个问题。在async void
内抛出的异常不会被我的常规手段捕获,并且在大多数情况下会使您的应用程序崩溃。
当您期望返回值时,应始终使用async Task
或async Task<T>
。
有关async
/ await
的一些指南,请参阅此MSDN post。
答案 1 :(得分:1)
嗯,问题是Everything来自同步Main()方法。如果你想编写异步代码,那么一个好的开始方法是创建一个异步的Main方法并在那里编写你的程序代码(i answered a similar question recently)。
class Program
{
static void Main(string[] args)
{
Task mainTask = MainAsync(args);
mainTask.Wait();
// Instead of writing more code here, use the MainAsync-method as your new Main()
}
static async Task MainAsync(string[] args)
{
// Write your programs code here, You can freely use the async / await pattern
}
}
结合允许你的&#34;开始&#34;返回任务的方法如下:
public static async Task Start()
{
var func = Edge.Func(@"
var esprima = require('esprima');
var stringify = require('json-stable-stringify');
var esprimaast = esprima.parse('var a=1;', { loc: true });
var esprimaStr = stringify(esprimaast, { space: 3 });
return function (data, callback) {
callback(null, 'Node.js welcomes ' + esprimaStr);
}
");
Console.WriteLine(await func(".NET"));
//Console.WriteLine("hello");
}
允许您在MainAsync方法中调用Start方法,如下所示:
static async Task MainAsync(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
await Start();
//wait for start to complete --- how should I do it??
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
我无法测试这个,因为我不知道静态&#34; Edge&#34;上课来自。但这是开始思考的好地方。
答案 2 :(得分:0)
从this question开始,您可以使用
sw.Start().GetAwaiter().GetResult;
或
Task.WaitAll(sw.Start());
分别来自Stephen Cleary和SnOrfus的答案。希望它有所帮助。