ZipEngine 角色在重启和忙碌状态之间停滞

本文提供有关在重启忙碌状态之间卡住 ZipEngine 角色并引发异常的问题的信息,指出:无法加载文件或程序集“WorkerAssembly - 尝试加载格式不正确的程序”。

原始产品版本:API 管理服务
原始 KB 数: 4464909

注意

请参阅有关 Azure 云服务故障排除系列的文章,这是实验室的第一个方案。 请确保已按照压缩器应用程序的实验室设置说明操作,以重新创建问题。

现象

压缩器应用程序的 ZipEngine 角色实例在重启忙碌状态之间不断循环,并在Azure 门户边栏选项卡中引发以下未经处理的异常:

Unhandled Exception: Could not load file or assembly 'WorkerAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format. at ZipEngine.WorkerRole.OnStart() at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(RoleType roleTypeEnum) at Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge. <InitializeRole> b__0() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()'[2018-08-12T11:28:39Z] Last exit time: [2018/08/12, 11:28:39.434].

对步骤进行故障排除

如果角色未启动,或者在初始化、繁忙和停止状态之间循环,可能是因为每次角色重启生命周期事件时,代码都引发了未经处理的异常。 因此,如果仔细查看上述调用堆栈,你会注意到辅助角色的 OnStart() 方法中存在未经处理的异常。 针对此类方案开始故障排除的最佳位置是检查 Microsoft Azure 事件日志 ,其中包含来自 Microsoft Azure 运行时的关键诊断输出,包括角色启动/停止、启动任务、OnStart 启动和停止、OnRun 启动、崩溃、回收等信息。

System.BadImageFormatException

Process ID: 5132
Process Name: WaWorkerHost
Thread ID: 4
AppDomain Unhandled Exception for role ZipEngine_IN_0
Exception: Could not load file or assembly 'WorkerAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.
at ZipEngine.WorkerRole.OnStart()
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(RoleType roleTypeEnum)
at Microsoft.WindowsAzure.ServiceRuntime.Implementation.Loader.RoleRuntimeBridge.
<InitializeRole>
b__0()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

现在,你对来自 Azure 事件日志Microsoft异常有了一点详细信息,指出由于 System.BadImageFormatException,托管辅助角色的进程无法加载程序集“WorkerAssembly”。 通常,当进程无法加载程序集时,捕获 Fusion 日志始终是一种好的做法。 在路径 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion 下进行以下注册表项更改以启用融合日志记录。 向所有人授予对融合日志路径文件夹C:\FusionLogs的完全控制权限。

屏幕截图显示 Fusion 下的注册表项。

检查“WorkerAssembly”的融合日志后,可能会获得进一步故障排除的详细信息。

*** Assembly Binder Log Entry  (8/12/2018 @ 12:51:00 PM) ***
The operation failed.
Bind result: hr = 0x8007000b. An attempt was made to load a program with an incorrect format.
Assembly manager loaded from:  D:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  E:\base\x64\WaWorkerHost.exe
--- A detailed error log follows. 
=== Pre-bind state information ===
LOG: DisplayName = WorkerAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///E:/approot
LOG: Initial PrivatePath = E:\approot
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = RoleManager
Calling assembly : ZipEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: E:\approot\ZipEngine.dll.config
LOG: Using host configuration file: 
LOG: Using machine configuration file from D:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///E:/approot/WorkerAssembly.DLL.
LOG: Assembly download was successful. Attempting setup of file: E:\approot\WorkerAssembly.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: WorkerAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
ERR: Invalid assembly platform or ContentType in file (hr = 0x8007000b).
ERR: Run-from-source setup phase failed with hr = 0x8007000b.
ERR: Failed to complete setup of assembly (hr = 0x8007000b). Probing terminated.

在融合日志中突出显示了上述错误消息,指出程序集的位数存在错误。 如果了解此 BadImageFormatException 文章,则此错误的最可能原因与以下相关:

“DLL 或可执行文件作为 64 位程序集加载,但它包含 32 位功能或资源。 例如,它依赖于 COM 互操作或调用 32 位动态链接库中的方法。 若要解决此异常,请将项目的 Platform 目标 属性设置为 x86(而不是 x64 或 AnyCPU)并重新编译。

若要找出程序集的位数,可以运行所选的任何 .NET 反编译程序。 使用 ILSpy 反编译“WorkerAssembly”后,你可能会发现以下程序集。

这是 32 位程序集(x86)。

// C:\WorkerAssembly.dll
// WorkerAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// Global type:
<Module>
// Architecture: x86
// Runtime: .NET 4.0

Azure 是一个 64 位的环境。 因此,针对 32 位目标编译的 .NET 程序集不会在 Azure 上运行。 若要解决此异常,请将“WorkerAssembly”项目的 Platform 目标 属性设置为 x64(而不是 x86 或 AnyCPU)并重新编译。

如果查看 ZipEngine 角色WorkerRole.cs代码,你会注意到下面两行代码实际上是加载程序集“WorkerAssembly”并执行某些函数。 由于它是一个 32 位程序集, 因此WaWorkerHost.exe 无法加载该程序集。

WorkerAssembly.WorkerAssembly workerAssembly = new WorkerAssembly.WorkerAssembly();
workerAssembly.DoWork();

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区