C#5 AsyncCtp BadImageFormatException

TDa*_*ver 5 async-await c#-5.0

请帮我这个,我一直在使用AsyncCtpLibrary和C#5 ctp编译器编写控制台应用程序.我第一次真正运行一个等待的代码,我得到了这个:

System.BadImageFormatException was unhandled
  Message=An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
  Source=AsyncCtpLibrary
  StackTrace:
    Server stack trace: 
       at [...].<Execute>d__1c.MoveNext()
       at [...].Execute()
       at [...].<Move>d__1d.MoveNext() in[..]:line 266
    Exception rethrown at [0]: 
       at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.<SetException>b__1(Object state)
       at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
       at System.Threading.ThreadPoolWorkQueue.Dispatch()
       at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
  InnerException: 
Run Code Online (Sandbox Code Playgroud)

我错过了要引用的dll吗?

重要的新东西
我失败的方法看起来像这样:

public async override Task<bool> Execute()
{
    //do stuff
    await stuff;
    //do other stuff
    await base.Execute()
    //do other stuff
    return true;
}
Run Code Online (Sandbox Code Playgroud)

我跟着Jon Skeet的建议试图一点一点地重现这个错误,现在我可以告诉我等待base.Execute()行是杀手!如果我对该行进行注释,则一切都会运行,如果我将其保留,则调用我的方法立即失败(不是在到达base.Execute()时).所以我假设ctp编译器做了一些怪异的事情.为什么?我该怎么做?这个虫子有多大?

老东西:

编辑:
至于32位/ 64位问题,我的系统是32位(在虚拟机内,请注意),据我所知,AsyncCtpLibrary.dll不包含非托管代码.我的所有项目(类库和单一控制台应用程序)都有这样的构建选项卡:截图
什么可能仍然是错的?


编辑:我还检查了Fusion日志查看器,AsyncCtpLibrary加载没有任何错误:

*** Assembly Binder Log Entry  (6/10/2011 @ 9:04:11 PM) ***    
The operation was successful.    
Bind result: hr = 0x0. The operation completed successfully.     
Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll    
Running under executable  C:\Users\Daver\Documents\Visual Studio 2010\Projects\[...]\bin\Debug\MyApp.exe

--- A detailed error log follows. 

=== Pre-bind state information ===    
LOG: User = WIN-N74LV38NLV3\Daver    
LOG: DisplayName = AsyncCtpLibrary, Version=1.0.4107.18181, Culture=neutral, PublicKeyToken=31bf3856ad364e35    
 (Fully-specified)    
LOG: Appbase = file:///C:/Users/Daver/Documents/Visual Studio 2010/Projects/[...]/bin/Debug/

LOG: Initial PrivatePath = NULL    
LOG: Dynamic Base = NULL    
LOG: Cache Base = NULL    
LOG: AppName = MyApp.exe    
Calling assembly : MyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===

LOG: This bind starts in default load context.    
LOG: Using application configuration file: C:\Users\Daver\Documents\Visual Studio 2010\Projects\[...]\bin\Debug\MyApp.exe.Config    
LOG: Using host configuration file:     
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.    
LOG: Post-policy reference: AsyncCtpLibrary, Version=1.0.4107.18181, Culture=neutral, PublicKeyToken=31bf3856ad364e35    
LOG: GAC Lookup was unsuccessful.    
LOG: Attempting download of new URL file:///C:/Users/Daver/Documents/Visual Studio 2010/Projects/[...]/bin/Debug/AsyncCtpLibrary.DLL.    
LOG: Assembly download was successful. Attempting setup of file: C:\Users\Daver\Documents\Visual Studio 2010\Projects\[...]\bin\Debug\AsyncCtpLibrary.dll    
LOG: Entering run-from-source setup phase.    
LOG: Assembly Name is: AsyncCtpLibrary, Version=1.0.4107.18181, Culture=neutral, PublicKeyToken=31bf3856ad364e35    
LOG: Binding succeeds. Returns assembly from C:\Users\Daver\Documents\Visual Studio 2010\Projects\[...]\bin\Debug\AsyncCtpLibrary.dll.    
LOG: Assembly is loaded in default load context.
Run Code Online (Sandbox Code Playgroud)

我还检查了编译器生成的类'MoveNext()方法的IL代码,<Execute>d__1c它引用的唯一程序集([assemblyName])是mscorlib,System.Core和AsyncCtpLibrary.


我查了清单我的两个DLL和AsyncCtpLibrary的,雷说.corflags 0x00000003 // ILONLY 32BITREQUIRED,AsyncCtpLibrary说.corflags 0x00000009 // ILONLY,我不确定这是否可以成为问题.

请帮助,我没有想法!

Jon*_*eet 6

编辑:我从编译器团队那里听说过,他们已经确认这是一个bug.它已经在他们的代码库中得到修复,所以我们希望在下一个版本/ beta/CTP中看到这个修复.该修复程序不会被反向移植到"正常"VS2010,因为它是一组非常不寻常的情况,至少在异步之前.


编辑:好的,我现在有一个非常简短但完整的程序来演示这个问题.我相信它是泛型调用基本方法的混合:

using System;
using System.Threading.Tasks;

public abstract class AsyncAction<T>
{
    public virtual Task<T> Execute()
    {
        // We never get this far
        Console.WriteLine("Execute called");
        return null;
    }
}

public class BoolAction : AsyncAction<bool>
{
    public async override Task<bool> Execute()
    {
        return await base.Execute();
    }
}

class Test
{
    static void Main()
    {
        BoolAction b = new BoolAction();
        b.Execute();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:好的,我想出了一个解决方法.基本上,要非虚拟地调用基类方法,编译器会在其中创建合成方法BoolAction.它有点错误,但我们可以做对:

public class BoolAction : AsyncAction<bool>
{
    public async override Task<bool> Execute()
    {
        return await BaseExecute();
    }

    private Task<bool> BaseExecute()
    {
        return base.Execute();
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,无论何时写作base.Execute,都要编写BaseExecute并插入额外的方法.在团队修复bug之前,解决方法并不算太糟糕.

编辑:我已经简化了一些示例 - 您不需要任何覆盖,特别是您不需要基类来公开Task<T>.调用任何base.Foo方法都可以:

public abstract class AsyncAction<T>
{
    public virtual T GetT()
    {
        return default(T);
    }
}

public class BoolAction : AsyncAction<bool>
{
#pragma warning disable 1998 // We're not awaiting anything
    public async void Execute()
    {
        base.GetT();
    }
#pragma warning restore 1998
}

class Test
{
    static void Main()
    {
        BoolAction b = new BoolAction();
        b.Execute();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:相反,我以前的想法,这不会影响到迭代器为好.不需要异步CTP ......

public abstract class Base<T>
{
    public virtual T GetT()
    {
        return default(T);
    }
}

public class Derived : Base<bool>
{
    public System.Collections.IEnumerator Foo()
    {
        base.GetT();
        yield break;
    }
}

class Test
{
    static void Main()
    {
        Derived d = new Derived();
        d.Foo().MoveNext();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:它也影响匿名函数...

using System;

public abstract class Base<T>
{
    public virtual T GetT()
    {
        return default(T);
    }
}

public class Derived : Base<bool>
{
    public void Foo()
    {
        Action x = () => base.GetT();
        x();
    }
}

class Test
{
    static void Main()
    {
        Derived d = new Derived();
        d.Foo();
    }
}
Run Code Online (Sandbox Code Playgroud)