gpt4 book ai didi

c# - 将同步方法更改为异步

转载 作者:行者123 更新时间:2023-11-30 16:04:41 25 4
gpt4 key购买 nike

我在谷歌上搜索了很多,阅读了不同的新手教程,但我认为我不明白正确的做法是什么。基本上,现有的同步代码会在服务器启动并运行时执行某些操作。有时,很少见,服务器需要更长的时间才能启动,所以我想将其包装在一些重试逻辑中。我构建了一个完全愚蠢的控制台应用程序来尝试了解 async 和 await 是如何工作的,并想出了这个:

    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

这样我应该将以前的同步方法转换为异步吗?

编辑

DoWork的伪代码(字符串目录,CancellationToken token)

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
}
}

最佳答案

简短的回答是否定的,您不能简单地通过用 Task.Run 包装操作并使方法返回 Task 来将所有类型的同步代码转换为异步代码。

通常,当所考虑的操作可能调用某些 IO 操作(文件系统读/写、网络或 Web 访问、数据库访问等)时,异步代码是有意义的。

例如,如果您有一个方法可以使用 FileStream.Read 等同步方法从文件中读取一些数据,然后对此类文件的内容进行一些 CPU 处理,那么您可以转换你的方法是异步的,方法是让它调用 FileStream.ReadAsync 而不是异步等待,直到 ReadAsync 使用 await 关键字完成,然后工作关于文件的内容(当然你必须改变返回Task的方法并且是async)。

这种情况的好处是没有线程等待 IO 操作完成并且线程很昂贵。

没有线程等待 IO 操作完成的好处在服务器应用程序(如 ASP.NET 网站)中非常重要,在这些应用程序中您期望有大量并发请求。但是,对于简单的应用程序,您可能一开始就不想使用异步代码。

如果您想在多个 CPU 内核上运行多个 CPU 密集型操作,您可以使用 Task.Run

例如,如果您有 4 个 CPU 内核,则通过 Task.Run 创建 4 个任务来处理一些数据是有意义的。考虑前面的例子,当你异步等待ReadAsync完成后,你可以将读取的结果拆分为4个部分(假设数据比较大),通过创建4个任务Task.Run,每一个都会处理一部分结果。然后,您可以使用 Task.WhenAll 异步等待 4 个任务完成。

关于c# - 将同步方法更改为异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34645667/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com