异步和快速路径优化

时间:2014-07-30 11:49:03

标签: c# .net c#-4.0 async-await .net-4.5

我正在对OWIN项目进行一些重构,我遇到了一些问题 c#快速路径优化。

所以我读到了关于预先计算的任务的最佳实践,使方法异步与否以及类似的东西。

更准确地说,在快速路径优化上:

基于任务的异步模式最佳实践(快速路径p9)http://www.microsoft.com/en-us/download/details.aspx?id=19957

与迭代器相同的指导,对于我来说,首先对我来说是可以理解的,因为我对TAP很新 http://social.msdn.microsoft.com/Forums/en-US/d9146792-1b9a-4807-a42e-29107c281cc4/can-awaiting-taskfromresult-introduce-concurrency?forum=async

所以这是我遇到的代码:

public class CustomMiddleware2 : OwinMiddleware
{
    public override async Task Invoke(IOwinContext context)
    {
        await InvokeInternal(context);
    }

    private Task InvokeInternal(IOwinContext context)
    {           
        if (Wacko.WhatDOuKnow)
        {
            context.Response.Redirect("/awesomeurl");

            //fast path
            return Task.FromResult<object>(null);
        }
        return Next.Invoke(context);
    }

    public CustomMiddleware2(OwinMiddleware next)
        : base(next)
    {

    }

}

这是我实际计划做的替代:

public class BetterOrNotMiddleware : OwinMiddleware
{
    public override Task Invoke(IOwinContext context)
    {
        if (Wacko.WhatDOuKnow)
        {
            context.Response.Redirect("/awesomeurl");

            //fast path
            return Task.FromResult<object>(null);

        }
        else
            return InvokeInternal(context);
    }

    private async Task InvokeInternal(IOwinContext context)
    {
        await Next.Invoke(context);
    }

    public BetterOrNotMiddleware(OwinMiddleware next)
        : base(next)
    {

    }

}

问题是,没有那么多差异。我不确定BetterOrNotMiddleware类是更优化还是更合适? 在Next.Invoke调用中等待我感觉更加充足,代码可能会让人感觉更容易理解,因为 它与使用迭代器进行异常处理的模式相同(上面的链接)

我可能会遗漏一些关于异步状态机或调用堆栈的东西会验证第二种方法,但我太新了,不能异步获取它。

但如果所有这些只是一个微优化,我不确定我是否想要更改应用程序中的所有中间件。好吧,我可能仍然是

2 个答案:

答案 0 :(得分:4)

这些几乎 完全相同。两个选项之间没有真正的区别,除了不必进行第二次方法调用(无论如何都可以由编译器优化)。

您可以只使用一种方法来完成所有事情:

public class BetterOrNotMiddleware : OwinMiddleware
{
    private static readonly Task CompletedTask = Task.FromResult<object>(null);
    public override Task Invoke(IOwinContext context)
    {
        if (Wacko.WhatDOuKnow)
        {
            context.Response.Redirect("/awesomeurl");
            // fast path
            return CompletedTask;
        }
        else
        {
            return Next.Invoke(context);
        }
    }
    // ...
}

编辑:每次都没有理由创建新任务,所以我改为使用静态完成的任务。

答案 1 :(得分:2)

在第一个代码示例中,为什么还要等待呢?

public override Task Invoke(IOwinContext context)
{
    return InvokeInternal(context);
}

第二个代码示例也是如此,您可以将两个样本完全快速路径,这样它们就足够相同。

InvokeInternal方法对我来说似乎没有意义,只是把逻辑直接放在Invoke中,即

public override Task Invoke(IOwinContext context)
{
    if (Wacko.WhatDOuKnow)
    {
        context.Response.Redirect("/awesomeurl");

        return Task.FromResult<object>(null);

    }
    return Next.Invoke(context);
}