C# 在同一HTTP请求ASP.NET核心C中混合异步和同步#
在同一个asp.net核心api调用中混合使用异步和同步调用是否是错误的做法 例如,在下面的代码中 方法CropBlackBroderOfAnImageAsync是一个异步方法 另一方面,保存图像以进行处理(文件、sourceFolderPath);is同步方法 原因:我正在同步调用SaveImageForProcessing,我希望使用它的结果来执行CropBlackRoderofAnimageAsync中的代码 完全代码回购 欢迎进行代码审查:C# 在同一HTTP请求ASP.NET核心C中混合异步和同步#,c#,asynchronous,asp.net-core,.net-core,C#,Asynchronous,Asp.net Core,.net Core,在同一个asp.net核心api调用中混合使用异步和同步调用是否是错误的做法 例如,在下面的代码中 方法CropBlackBroderOfAnImageAsync是一个异步方法 另一方面,保存图像以进行处理(文件、sourceFolderPath);is同步方法 原因:我正在同步调用SaveImageForProcessing,我希望使用它的结果来执行CropBlackRoderofAnimageAsync中的代码 完全代码回购 欢迎进行代码审查: 公共异步任务CropBlackOrderOfa
公共异步任务CropBlackOrderOfaImage(IFormFile)
{
var extension=Path.GetExtension(file.FileName);
var newFileName=Guid.NewGuid().ToString();//由于安全原因,请为文件创建新名称。
var fileNameSource=newFileName+扩展名;
var sourceFolderPath=Path.Combine(Directory.GetCurrentDirectory(),“Images\\Source”,fileNameSource);
var filenamedstination=newFileName+“Result”+扩展名;
var destinationFolderPath=Path.Combine(Directory.GetCurrentDirectory(),“Images\\Destination”,fileNameDestination);
SaveImageForProcessing(文件,sourceFolderPath);
wait_imageCropBlackBroderService.CropBlackBroderOfAnImageAsync(sourceFolderPath,destinationFolderPath);
返回(sourceFolderPath、destinationFolderPath);
}
私有void SaveImageForProcessing(格式文件,字符串路径)
{
使用(var bits=newfilestream(路径,FileMode.Create))
{
文件.CopyTo(位);
}
}
是的,这是一种不好的做法。如果在异步代码中使用长同步操作,那么也将冻结所有其他异步代码。原因是异步代码通常在一个线程中运行。如果该线程正忙于等待一个长操作,它将无法处理其他异步代码
相反,只需使用,并将您的
SaveImageForProcessing
转换为异步函数。是的,这是一种不好的做法。如果在异步代码中使用长同步操作,那么也将冻结所有其他异步代码。原因是异步代码通常在一个线程中运行。如果该线程正忙于等待一个长操作,它将无法处理其他异步代码
相反,只需使用,并将您的
SaveImageForProcessing
转换为异步函数。这一切都取决于您的应用程序。在异步函数中调用同步函数完全可以。不过,您可能会在桌面上留下一些性能。不过,如果您已经在以异步方式进行操作,那么在异步函数中,您也可以使用异步文件IO方法。async函数中的代码仍然可以是异步的,并且仍然按照正确的顺序执行(这似乎是您所关心的),您只需等待结果并在以后的代码行中使用它们
更大的问题是试图屏蔽async
调用,使其看起来像sync
,反之亦然
你可以看看这些帖子:
这一切都取决于您的应用程序。在异步函数中调用同步函数完全可以。不过,您可能会在桌面上留下一些性能。不过,如果您已经在以异步方式进行操作,那么在异步函数中,您也可以使用异步文件IO方法。async函数中的代码仍然可以是异步的,并且仍然按照正确的顺序执行(这似乎是您所关心的),您只需等待结果并在以后的代码行中使用它们 更大的问题是试图屏蔽
async
调用,使其看起来像sync
,反之亦然
你可以看看这些帖子:
原因:我正在同步调用SaveImageForProcessing,我希望使用它的结果来执行CropBlackRoderofAnimageAsync中的代码
我想你误解了异步的意思。当代码异步运行时,这意味着当前线程在等待时可以自由地执行其他操作。阅读这篇文章可能会有所帮助。它有一个非常有用的关于做早餐的说明
听起来您相信运行异步意味着代码将在其他地方运行,而您的其他代码正在运行。这就是所谓的“平行”
async
和await
的目的是使启动异步任务变得容易,并在准备好结果时返回到它们。在您的情况下,由于您希望立即获得结果,因此可以使SaveImageForProcessing
异步,使用CopyToAsync
和等待它。然后您可以立即使用结果
因为您使用了wait
,当您到达调用cropblackbroderofanimagesasync
的线路时,可以保证SaveImageForProcessing
已完全完成
public async Task<(string sourceFolderPath, string destinationFolderPath)> CropBlackBorderOfAnImage(IFormFile file)
{
var extension = Path.GetExtension(file.FileName);
var newFileName = Guid.NewGuid().ToString();//Create a new Name for the file due to security reasons.
var fileNameSource = newFileName + extension;
var sourceFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Images\\Source", fileNameSource);
var fileNameDestination = newFileName + "Result" + extension;
var destinationFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Images\\Destination", fileNameDestination);
await SaveImageForProcessing(file, sourceFolderPath);
await _imageCropBlackBroderService.CropBlackBroderOfAnImageAsync(sourceFolderPath, destinationFolderPath);
return (sourceFolderPath, destinationFolderPath);
}
private async Task SaveImageForProcessing(IFormFile file, string path)
{
using (var bits = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(bits);
}
}
公共异步任务CropBlackOrderOfaImage(IFormFile)
{
var extension=Path.GetExtension(file.FileName);
var newFileName=Guid.NewGuid().ToString();//由于安全原因,请为文件创建新名称。
var fileNameSource=newFileName+扩展名;
var sourceFolderPath=Path.Combine(Directory.GetCurrentDirectory(),“Images\\Source”,fileNameSource);
var filenamedstination=newFileName+“Result”+扩展名;
var destinationFolderPath=Path.Combine(Directory.GetCurrentDirectory(),“Images\\Destination”,fileNameDestination);
等待SaveImageForProcessing(文件,sourceFolderPath);
wait_imageCropBlackBroderService.CropBlackBroderOfAnImageAsync(sourceFolderPath,destinationFolderPath);
返回(sourceFolderPath、destinationFolderPath);
}
专用异步任务SaveImageForProcessing(格式化文件,字符串路径)
{
使用(var位=新文件流(路径,Fil
public async Task<(string sourceFolderPath, string destinationFolderPath)> CropBlackBorderOfAnImage(IFormFile file)
{
var extension = Path.GetExtension(file.FileName);
var newFileName = Guid.NewGuid().ToString();//Create a new Name for the file due to security reasons.
var fileNameSource = newFileName + extension;
var sourceFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Images\\Source", fileNameSource);
var fileNameDestination = newFileName + "Result" + extension;
var destinationFolderPath = Path.Combine(Directory.GetCurrentDirectory(), "Images\\Destination", fileNameDestination);
await SaveImageForProcessing(file, sourceFolderPath);
await _imageCropBlackBroderService.CropBlackBroderOfAnImageAsync(sourceFolderPath, destinationFolderPath);
return (sourceFolderPath, destinationFolderPath);
}
private async Task SaveImageForProcessing(IFormFile file, string path)
{
using (var bits = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(bits);
}
}