我有一个async方法:
public async Task<string> GenerateCodeAsync()
{
string code = await GenerateCodeService.GenerateCodeAsync();
return code;
}
Run Code Online (Sandbox Code Playgroud)
我需要从同步方法中调用此方法.
如何在不必复制GenerateCodeAsync方法的情况下执行此操作以使其同步工作?
更新
然而找不到合理的解决方案
但是,我看到HttpClient已经实现了这种模式
using (HttpClient client = new HttpClient())
{
// async
HttpResponseMessage responseAsync = await client.GetAsync(url);
// sync
HttpResponseMessage responseSync = client.GetAsync(url).Result;
}
Run Code Online (Sandbox Code Playgroud) 我在我创建的Web API中进行了以下操作:
// GET api/<controller>
[HttpGet]
[Route("pharmacies/{pharmacyId}/page/{page}/{filter?}")]
public CartTotalsDTO GetProductsWithHistory(Guid pharmacyId, int page, string filter = null ,[FromUri] bool refresh = false)
{
return delegateHelper.GetProductsWithHistory(CustomerContext.Current.GetContactById(pharmacyId), refresh);
}
Run Code Online (Sandbox Code Playgroud)
对此Web服务的调用是通过以下方式通过Jquery Ajax调用完成的:
$.ajax({
url: "/api/products/pharmacies/<%# Farmacia.PrimaryKeyId.Value.ToString() %>/page/" + vm.currentPage() + "/" + filter,
type: "GET",
dataType: "json",
success: function (result) {
vm.items([]);
var data = result.Products;
vm.totalUnits(result.TotalUnits);
}
});
Run Code Online (Sandbox Code Playgroud)
我见过一些以这种方式实现上一个操作的开发人员:
// GET api/<controller>
[HttpGet]
[Route("pharmacies/{pharmacyId}/page/{page}/{filter?}")]
public async Task<CartTotalsDTO> GetProductsWithHistory(Guid pharmacyId, int page, string filter = null ,[FromUri] bool refresh = false)
{
return …Run Code Online (Sandbox Code Playgroud) 好吧,我有以下问题,希望你能帮助我:
我想创建一个带后台工作程序的WPF应用程序,用于更新richtextboxes和其他UI元素.这个后台工作者应该处理一些数据,例如处理文件夹的内容,做一些解析等等.因为我想在Main类之外移动尽可能多的代码,所以我创建了一个类MyProcess.cs,如下所示(事实上,到目前为止,这个类没有多大意义,如果有更多的处理元素,这个问题已经解决了).一般功能应该是:
this.folderContent)DoWork()将调用该方法(我知道,这个现在在一个新线程中运行)RunWorkerCompleted()则调用该方法(在UI线程中运行),该方法应通过方法的返回参数更新WPF RichTextBox最后一步导致带有注释的InvalidOperationsException,"调用线程无法访问此对象,因为另一个线程拥有它".我读了一下后台工作者类及其功能.所以我认为它与方法中的this.formatedFilenames.Inlines.Add(new Run(...))调用Execute()有关MyProcess.如果我用字符串列表或类似的东西替换Paragraph属性(没有额外的new()调用),我可以通过get方法访问此成员而不会出现任何问题.与我发现的后台工作者相关的所有示例都只返回基本类型或简单类.
MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
this.process = new MyProcess();
this.worker = new BackgroundWorker();
this.worker.DoWork += worker_DoWork;
this.worker.RunWorkerCompleted += worker_RunWorkerCompleted;
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
this.process.Execute((string[])e.Argument);
e.Result = this.process.Paragraph();
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.rtbFolderContent.Document.Blocks.Clear();
// the next line causes InvalidOperationsException:
// The calling thread cannot access this object …Run Code Online (Sandbox Code Playgroud) 简短的问题:
为什么.Net Framework添加了很多*Async版本的方法而不是开发人员只是Task.Run用来异步运行同步方法?
详细问题:
Tasks我不明白的是库中*Async方法的目的.
假设您有两行代码:
F1();
F2();
Run Code Online (Sandbox Code Playgroud)
关于数据/控制流程,只有两种情况:
F2需要在F1完成后执行.F2不需要等待F1完成.我没有看到任何其他情况.我没有看到任何一般需要知道执行某些功能的具体线程(除了UI).线程中代码的基本执行模式是同步的.并行性需要多个线程.异步性基于并行性和代码重新排序.但基地仍然是同步的.
当F1工作量很小时,差异无关紧要.但是当A花费大量时间完成时,我们可能需要查看情况,如果F2不需要等待F1完成,我们可以F1并行运行F2.
很久以前我们使用线程/线程池来做到这一点.现在我们有Tasks.
如果我们要运行F1和F2在同时,我们可以这样写:
var task1 = Task.Run(F1);
F2();
Run Code Online (Sandbox Code Playgroud)
任务很酷,我们可以await在最终需要完成任务的地方使用.
到目前为止,我认为没有必要制作F1Async()方法.
现在,我们来看一些特殊情况.我看到的唯一真正特殊情况是UI.UI线程是特殊的并且停止它会使UI冻结很糟糕.正如我所看到的,Microsoft建议我们标记UI事件处理程序async.标记方法async意味着我们可以使用await关键字基本上在另一个线程上安排繁重的处理并释放UI线程,直到处理完成.
我不能再得到的是为什么我们需要任何*Async方法来等待它们.我们总是可以写await Task.Run(F1);.我们为什么需要F1Async?
你可能会说*Async方法使用一些特殊的魔法(比如处理外部信号),使它们比同步方法更有效.事情是,我不认为这是事实.
我们来看看Stream.ReadAsync例如.如果你看一下源代码,ReadAsync就浪费几百行铃声和口哨代码来创建一个只调用同步Read方法的任务.那为什么我们需要呢?为什么不直接使用Task.Run带Stream.Read …