繁体   English   中英

Task.FromResult 与没有等待的异步

[英]Task.FromResult vs async without await

下面的两个代码片段是否等效?

使用 Task.FromResult

public Task<string> Foo() {
    return Task.FromResult("foo");
}

使用异步而不等待

public async Task<string> Foo() {
    return "foo";
}

如果不相等,有什么区别?

对于最终用户来说,答案是Yes

但是从C# 编译器生成的代码会有很大的不同。
async / await正在生成 state 机器。

如果您有兴趣,可以在此处此处查看生成的代码以及有关 state 机器的更多信息。

唯一的区别是 async 将异常包装在 return Task 中,堆栈跟踪由您await的位置确定。

您基本上必须在性能和安全性之间做出决定。

就像前面提到的用户一样,最终用户的结果将是相同的,但编译器将使用 state 机器。

使用https://sharplab.io/可以很容易地看到/分析这些代码更改

所以使用以下方法:

public class SomeClass 
{

    public async Task<bool> DidObjectChange(string fontFamily, string glyph, int size, string color, CompareToThisClass compareTo)
    {
        if(fontFamily != compareTo.FontFamily)
            return true;

        if(glyph != compareTo.Glyph)
            return true;

        if (size != compareTo.Size)
            return true;

        if (color != compareTo.Color)
            return true;

        return false;
    }
    
   
}

public class CompareToThisClass
{
    public string FontFamily { get; set; }       
    public string Glyph { get; set; }     
    public int Size { get; set; }     
    public string Color { get; set; }     
}

返回以下编译代码:

[StructLayout(LayoutKind.Auto)]
[CompilerGenerated]
private struct <DidObjectChange>d__0 : IAsyncStateMachine
{
    public int <>1__state;

    public AsyncTaskMethodBuilder<bool> <>t__builder;

    public string fontFamily;

    public CompareToThisClass compareTo;

    public string glyph;

    public int size;

    public string color;

    private void MoveNext()
    {
        bool result;
        try
        {
            result = fontFamily != compareTo.FontFamily || glyph != compareTo.Glyph || size != compareTo.Size || ((color != compareTo.Color) ? true : false);
        }
        catch (Exception exception)
        {
            <>1__state = -2;
            <>t__builder.SetException(exception);
            return;
        }
        <>1__state = -2;
        <>t__builder.SetResult(result);
    }

    void IAsyncStateMachine.MoveNext()
    {
        //ILSpy generated this explicit interface implementation from .override directive in MoveNext
        this.MoveNext();
    }

    [DebuggerHidden]
    private void SetStateMachine(IAsyncStateMachine stateMachine)
    {
        <>t__builder.SetStateMachine(stateMachine);
    }

    void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
    {
        //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
        this.SetStateMachine(stateMachine);
    }
}

[AsyncStateMachine(typeof(<DidObjectChange>d__0))]
public Task<bool> DidObjectChange(string fontFamily, string glyph, int size, string color, CompareToThisClass compareTo)
{
    <DidObjectChange>d__0 stateMachine = default(<DidObjectChange>d__0);
    stateMachine.<>t__builder = AsyncTaskMethodBuilder<bool>.Create();
    stateMachine.fontFamily = fontFamily;
    stateMachine.glyph = glyph;
    stateMachine.size = size;
    stateMachine.color = color;
    stateMachine.compareTo = compareTo;
    stateMachine.<>1__state = -1;
    stateMachine.<>t__builder.Start(ref stateMachine);
    return stateMachine.<>t__builder.Task;
}

在没有异步的情况下使用它:

public class SomeClass 
{

    public Task<bool> DidObjectChange(string fontFamily, string glyph, int size, string color, CompareToThisClass compareTo)
    {
        if(fontFamily != compareTo.FontFamily)
            return Task.FromResult(true);

        if(glyph != compareTo.Glyph)
            return Task.FromResult(true);

        if (size != compareTo.Size)
            return Task.FromResult(true);

        if (color != compareTo.Color)
            return Task.FromResult(true);

        return Task.FromResult(false);
    }
    
   
}

public class CompareToThisClass
{
    public string FontFamily { get; set; }       
    public string Glyph { get; set; }     
    public int Size { get; set; }     
    public string Color { get; set; }     
}

返回以下编译代码:

public Task<bool> DidObjectChange(string fontFamily, string glyph, int size, string color, CompareToThisClass compareTo)
{
    if (fontFamily != compareTo.FontFamily)
    {
        return Task.FromResult(true);
    }
    if (glyph != compareTo.Glyph)
    {
        return Task.FromResult(true);
    }
    if (size != compareTo.Size)
    {
        return Task.FromResult(true);
    }
    if (color != compareTo.Color)
    {
        return Task.FromResult(true);
    }
    return Task.FromResult(false);
}

所以 TL;DR:开销要少得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM