C# 下面的代码序列在C中有意义吗#
我没有经常使用async/Wait,对它们也不是很熟悉。我试图使一个同步的操作异步运行。您能否告诉我以下代码片段是否有意义:C# 下面的代码序列在C中有意义吗#,c#,async-await,C#,Async Await,我没有经常使用async/Wait,对它们也不是很熟悉。我试图使一个同步的操作异步运行。您能否告诉我以下代码片段是否有意义: public static async Task<string> FileVersionAsync(string localFilePath) { FileVersionInfo versionInfo; try { versionInfo = await Task.FromResult(FileVersionInfo.
public static async Task<string> FileVersionAsync(string localFilePath)
{
FileVersionInfo versionInfo;
try
{
versionInfo = await Task.FromResult(FileVersionInfo.GetVersionInfo(localFilePath));
}
catch (SecurityException)
{
return "File Version Checker does not have permission to read file version";
}
catch (FileNotFoundException)
{
return "Unable to find configured file";
}
if (versionInfo.FileVersion == null)
return "N/A";
return versionInfo.FileVersion;
}
publicstaticasync任务FileVersionAsync(字符串localFilePath)
{
FileVersionInfo版本信息;
尝试
{
versionInfo=wait Task.FromResult(FileVersionInfo.GetVersionInfo(localFilePath));
}
catch(SecurityException)
{
返回“文件版本检查器没有读取文件版本的权限”;
}
捕获(FileNotFoundException)
{
返回“找不到配置的文件”;
}
if(versionInfo.FileVersion==null)
返回“不适用”;
返回versionInfo.FileVersion;
}
否。似乎完全没有必要使此方法异步,因为Task.FromResult立即准备就绪。添加任务
,等待
和异步
不要使某些内容异步;它们仅仅提供了在异步代码发生时使用异步代码的管道。在您的示例中:它从不异步发生,所以您所做的只是增加管道开销,而没有任何好处
编译器将生成大量的额外代码,这些代码将永远不会被命中,因为当它到达await
时,它将发现任务已经完成,并将在现有线程上继续
要真正实现异步,您需要。。。异步的东西。这可能是外部IO,也可能是与线程相关的——但请注意,简单地跳到另一个线程并不能为您带来任何好处:它只是添加了一个上下文切换
如果有一个
FileVersionInfo.getversioninfoancy
方法,您所做的可能是值得的。不,这没有意义。
使函数异步的唯一原因是函数内部的某个地方等待其他异步函数。事实上,如果您忘记在某处等待,编译器会警告您
异步等待语法是作为其他任务函数(如task.ContinueWith、task.FromResult、task.FromException等)的替代品而发明的
在中间搜索某处,等待。< /P> 如果厨师必须准备早餐,他就开始烧开水。但是他没有等水烧好,而是开始切面包,做其他事情。只有在他无事可做之后,他才开始无所事事地等待水烧开,然后泡茶
类似地:如果程序必须等待外部进程执行请求,如数据库查询、将数据写入文件、从internet获取信息等。async await确保线程不会空闲等待。相反,您的线程会向上移动其调用堆栈,查看其中一个调用方是否可以继续工作,而不需要另一个进程的结果 您将在以下代码中看到这一点:public async Task<string> ReadTextFile()
{
StreamReader txtReader = File.OpenText(...);
// read the complete text file; don't wait until finished yet
Task<String> taskTxt = txtReader.ReadToEndAsync();
// as we didn't use await, we can continue processing:
DoSomething();
// now we need the result from the read action: await for it
// the result of await Task<TResult> is the TResult:
string importedTxt = await taskTxt;
return importedTxt;
}
这将确保无论何时线程必须等待某项操作,它都可以执行其他操作,因此您的GUI保持响应。不确定您要执行什么操作。您编写的代码将使用async/await,但不会异步执行。它将阻止FileVersionInfo.GetVersionInfo()。如果您想让代码真正异步执行,请将Task.FromResult替换为Task.Run。@这不会使其异步执行。它将同步执行,但在另一个线程上并行执行(这可能是OP想要的)。最好使用异步版本的
GetVersionInfo
(如果存在)。在所有情况下都返回字符串是不好的。代码编译@LarsTech。Task。FromResult
不是立即“就绪”的。它会一直阻止,直到GetVersionInfo
返回。然后,是的,任务
已经完成了。好吧,这取决于你所说的立即准备好是什么意思-我的意思是它一被调用就返回(这是立即的合理定义)。当然,它只在GetVersionInfo返回后调用。同意这一点,答案中的措辞在这一点上听起来有点不清楚。
public async void Button_Clicked(object sender, EventArgs e)
{
// indicate you will do something time consuming:
this.ProgressBar1.Visible = true;
await DoSomethingTimeconsumingAsync(...);
// finished:
this.progressBar1.Visible = false;
}