我在谷歌上搜索了很多并阅读了不同的菜鸟教程,但我认为我不明白正确的做法是什么。基本上,现有的同步代码会在服务器启动并运行时执行某些操作。有时(很少见),服务器需要更长的时间才能启动,因此我想将其包装在一些重试逻辑中。我构建了一个完全愚蠢的控制台应用程序来尝试了解 async 和 wait 是如何工作的,并想出了这个:
private static int counter = 0;
static void Main(string[] args)
{
DoIt();
Console.ReadLine();
}
static bool LongTask()
{
if (counter == 2)
{
Console.WriteLine("finally true");
Thread.Sleep(1000);
return true;
}
counter++;
Console.WriteLine("false");
Thread.Sleep(1000);
return false;
}
public static Task<bool> WrapperLongTask()
{
Console.WriteLine("wrapper called");
return Task.Run(() => LongTask());
}
public static async Task DoIt()
{
Console.WriteLine("hi");
var result = await WrapperLongTask();
while (result != true)
{
result = await WrapperLongTask();
Console.WriteLine("inside while loop");
}
Console.WriteLine($"outside while loop {result}");
Console.WriteLine("bye");
}
我的 LongTask 函数代表我当前的函数,该函数通常第一次就可以工作。然后调用这个方法可以吗
Task.Run(() => LongTask())
假设这是“好的”,那么我基本上会在我当前方法的实际代码中创建它DoWork()
.
Task DoWorkAsync(....) {
return Task.Run(() => DoWork()
}
基本上只是将其包装在 Task.Run 中,将返回类型更改为 Task。然后当我稍后调用这个方法时,我会做类似的事情
var x = await DoWorkAsync;
// do more stuff with x
这样我应该将以前的同步方法转换为异步吗?
Edit
DoWork 的伪代码(字符串目录,CancellationToken 令牌)
var files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
foreach (var file in files) {
try {
token.ThrowIfCancellationRequested();
var fileName = Path.GetFileName(file);
// check if file already exists on server, if not, upload it
}
catch (Exception exception) {
// error handling
}
}