请帮助我解决这个问题,我一直在使用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: 是否缺少要引用的dll?
重要的新产品
我失败的方法如下所示:
public async override Task<bool> Execute()
{
//do stuff
await stuff;
//do other stuff
await base.Execute()
//do other stuff
return true;
}我遵循乔恩·斯基特的建议,试图一点一点地重现这个错误,现在我可以看出,等待base.Execute()线才是杀手!如果我注释了这一行,那么所有东西都会运行,如果我把它放在里面,调用我的方法就会立即失败(而不是在到达base.Execute()时)。所以我假设ctp编译器会做一些奇怪的事情。为什么?我不应该做什么?虫子有多大?
老东西:
编辑:
至于32位/64位问题,我的系统是32位(在虚拟机中,请注意),据我所知,AsyncCtpLibrary.dll不包含非托管代码。我的所有项目(类库和单个控制台应用程序)都有如下构建选项卡:

,还有什么可能还是错的?
编辑:我还检查了融合日志查看器,加载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.我还检查了编译器生成的类的MoveNext()方法的<Execute>d__1c IL代码,它引用的唯一程序集(assemblyName)是mscorlib、System.Core和AsyncCtpLibrary。
我检查了我的dll和的dll和AsyncCtpLibrary,我的.corflags 0x00000003 // ILONLY 32BITREQUIRED说,AsyncCtpLibrary说.corflags 0x00000009 // ILONLY,我不确定这是否是问题所在。
,请帮帮忙,我没有主意了!
发布于 2011-06-11 08:21:52
编辑:我已经收到编译器团队的回复,他们已经确认它是一个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();
}
}编辑:好的,我想出了一个解决办法。基本上,要非虚拟地调用基类方法,编译器将在BoolAction中创建一个合成方法.这有点不对,但我们可以做得对:
public class BoolAction : AsyncAction<bool>
{
public async override Task<bool> Execute()
{
return await BaseExecute();
}
private Task<bool> BaseExecute()
{
return base.Execute();
}
}因此,无论何时编写base.Execute,编写BaseExecute并插入额外的方法。这不是很糟糕的解决办法,直到团队修复错误。
编辑:我已经稍微简化了这个例子--您不需要任何重写,特别是不需要基类来公开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();
}
}编辑:与我之前的想法相反,这也会影响迭代器。不需要异步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();
}
}编辑:它也会影响匿名功能.
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();
}
}发布于 2011-06-14 15:01:47
发布于 2011-06-08 20:08:36
当您尝试在64位环境中加载32位DLL时,通常会发生此异常。
如果在64位操作系统上运行,请尝试更改项目设置以直接编译x86 (而不是AnyCPU)。
(这听起来可能有点倒转,但这是因为如果要加载外部32位DLL,则需要强制整个项目为32位。)
https://stackoverflow.com/questions/6283644
复制相似问题