我对C#中的异步编程有点陌生,我还在努力应对一个小的但令人沮丧的挑战。
我有一个运行良好的ASP.Net MVC WEB。另一方面,我创建了这个WEB客户端方法:
public async Task<DTOVArt> GetVArtFormArt(DTOArt art)
{
using (var client = GetHttpClient())
{
var response = await client.GetAsync("api/APIVArt/Get/" + art.ART_ID);
if (!response.IsSuccessStatusCode) return null;
var arts = await response.Content.ReadAsAsync<DTOVArt>();
return arts;
}
}似乎很好用..。
这个方法是从WPF视图模型调用的,这就是我的问题所在。
private DTOVObs TransFormAaretsGang(DTOAaretsGang aaretsGang)
{
var dtovObs = new DTOVObs();
using (var artservice = new ArtService())
{
artservice.GetVArtFormArt(new DTOArt() {ART_ID = aaretsGang.ART_ID}).ContinueWith(t =>
{
dtovObs.Familie_id = t.Result.Familie_id;
dtovObs.Gruppe_id = t.Result.Gruppe_id;
dtovObs.ART_ID = t.Result.ART_ID;
if (aaretsGang.Dato != null) dtovObs.Aarstal = aaretsGang.Dato.Value.Year;
return dtovObs;
});
}
return dtovObs;
}问题是,最后一个方法在返回语句到达ContinueWith语句块之前执行返回语句,这实际上设置了应该返回的类中的值。
任何试图执行任何类型的等待()或使用.Result而不是ContinueWith的尝试都会阻止一切。
如果我在ContinueWith块中执行返回操作,C#编译器会说该方法缺少一个返回语句,这是正确的。
发布于 2015-07-25 12:28:33
这就是异步的本质。因为您的调用是异步的,所以它将在稍后执行,下面的代码只是继续执行。
尝试添加一个await,如果这是调用的root,只需删除ContinueWith,通常是一个事件处理程序:
private async Task<DTOVObs> TransFormAaretsGang(DTOAaretsGang aaretsGang)
{
var dtovObs = new DTOVObs();
DTOVArt Result = await artservice.GetVArtFormArt(new DTOArt() {ART_ID = aaretsGang.ART_ID});
dtovObs.Familie_id = Result.Familie_id;
dtovObs.Gruppe_id = Result.Gruppe_id;
dtovObs.ART_ID = Result.ART_ID;
if (aaretsGang.Dato != null)
dtovObs.Aarstal = aaretsGang.Dato.Value.Year;
return dtovObs;
}如果您仍然希望返回一个异步任务,以便任何调用此方法的调用者都可以等待结果,请尝试:
private async Task<DTOVObs> TransFormAaretsGang(DTOAaretsGang aaretsGang)
{
using (var artservice = new ArtService())
{
return artservice.GetVArtFormArt(new DTOArt() {ART_ID = aaretsGang.ART_ID}).ContinueWith(t =>
{
dtovObs.Familie_id = t.Result.Familie_id;
dtovObs.Gruppe_id = t.Result.Gruppe_id;
dtovObs.ART_ID = t.Result.ART_ID;
if (aaretsGang.Dato != null) dtovObs.Aarstal = aaretsGang.Dato.Value.Year;
return dtovObs;
});
}
}发布于 2015-07-27 10:32:25
当您使用异步/等待时,不必再使用ContinueWith了。ContinueWith的意思是:等到前面的内容完成,然后使用结果来执行下一个操作。
异步等待为您做这件事。
假设您有一个异步函数。如果返回类型为<TResult,则所有异步函数都返回任务(用于空返回)或任务TResult >
private async Task<int> SlowAdditionAsync(int a, int b)
{
await Task.Delay(TimeSpan.FromSeconds(5); // causing the slow part
return a + b;
}用法:
private async Task PerformSlowAddition()
{
int a = ...;
int b = ...;
int x =await SlowAditionAsync(a, b);
// the statement after the await, the task is finished, the result is in x.
// You can used the result as if you used Continuewith:
DisplayAddition(x);
}或者,如果您想在计算过程中做其他事情:
private async Task PerformSlowAddition()
{
int a = ...;
int b = ...;
var taskSlowAddition = SlowAditionAsync(a, b);
DoSomethingElse(); // while the calculator does its thing
// now we need the result:
int x = await taskSlowAddition;
// no need to use ContinueWith, the next statement will be executed:
DisplayAddition(x);
}请记住:
只有一个异步函数不需要返回任务,这就是均衡器:
private async void OnButton1_Clicked(object sender, ...)
{
var taskX = DosomethingAsync(...)
DoSomethingElse();'
// now we need the result of taskX:
var x = await TaskX;
ProcessReault(x)
}注意,尽管事件处理程序不返回任务,但它仍然是异步的。
如果您有一些语句需要在用户界面保持响应时在后台运行,请使用Task.Factory.StartNew()或更现代的Task.Run():
private int SlowCalculation(int a, int b)
{
// do something really difficult and slow
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
return a + b;
}
// make it async:
private async Task<int> SlowCalculationAsync(int a, int b)
{
return await Task.Run( () => SlowCalculation(a, b));
}用法:
private async Task CalculateAsync()
{
int a = ...;
int b = ...;
int x = await SlowCalculationAsync(a, b);
Display(x);
}
private async void OnButton1_clicked(object sender, ...)
{
await CalculateAsync();
}https://stackoverflow.com/questions/31626411
复制相似问题