首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# ContinueWith /返回

C# ContinueWith /返回
EN

Stack Overflow用户
提问于 2015-07-25 12:24:23
回答 2查看 2.1K关注 0票数 1

我对C#中的异步编程有点陌生,我还在努力应对一个小的但令人沮丧的挑战。

我有一个运行良好的ASP.Net MVC WEB。另一方面,我创建了这个WEB客户端方法:

代码语言:javascript
复制
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视图模型调用的,这就是我的问题所在。

代码语言:javascript
复制
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#编译器会说该方法缺少一个返回语句,这是正确的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-25 12:28:33

这就是异步的本质。因为您的调用是异步的,所以它将在稍后执行,下面的代码只是继续执行。

尝试添加一个await,如果这是调用的root,只需删除ContinueWith,通常是一个事件处理程序:

代码语言:javascript
复制
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;
}

如果您仍然希望返回一个异步任务,以便任何调用此方法的调用者都可以等待结果,请尝试:

代码语言:javascript
复制
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;
            });
        }
    }
票数 1
EN

Stack Overflow用户

发布于 2015-07-27 10:32:25

当您使用异步/等待时,不必再使用ContinueWith了。ContinueWith的意思是:等到前面的内容完成,然后使用结果来执行下一个操作。

异步等待为您做这件事。

假设您有一个异步函数。如果返回类型为<TResult,则所有异步函数都返回任务(用于空返回)或任务TResult >

代码语言:javascript
复制
private async Task<int> SlowAdditionAsync(int a, int b)
{
    await Task.Delay(TimeSpan.FromSeconds(5); // causing the slow part
    return a + b;
}

用法:

代码语言:javascript
复制
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);
}

或者,如果您想在计算过程中做其他事情:

代码语言:javascript
复制
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);
}

请记住:

  • 所有使用返回任务或任务的函数的函数都应该声明为异步
  • 所有异步函数都返回任务--如果它们返回TResult,则返回void或Task。
  • 任务返回有一个例外:事件处理程序返回无效
  • 调用异步函数之后,您可以做其他事情。
  • 当您需要使用结果时,请等待
  • 您只能等待任务或任务
  • 等待任务的值是TResult

只有一个异步函数不需要返回任务,这就是均衡器:

代码语言:javascript
复制
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():

代码语言:javascript
复制
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));
}

用法:

代码语言:javascript
复制
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();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31626411

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档