F# Azure Functions无法获取EXECUTION_CONTEXT_FUNCTIONDIRECTORY的技术咨询
我之前在开发F# Azure Functions时也碰到过完全一样的问题——文档里提到的EXECUTION_CONTEXT_FUNCTIONDIRECTORY环境变量拿不到,ExecutionContext也找不到FunctionDirectory属性。后来查了版本差异和官方更新,整理出两个适配不同运行模型的解决方案:
进程内(In-Process)模型下的处理
如果你的函数用的是进程内模型(依赖Microsoft.Azure.WebJobs包),可以试试这两种方式:
拼接函数应用目录与函数名
ExecutionContext虽然没有FunctionDirectory,但它提供了FunctionAppDirectory(函数应用的根目录)。默认情况下,每个函数的代码文件都放在根目录下与FunctionName同名的文件夹里,所以可以直接拼接路径:open Microsoft.Azure.WebJobs open System.IO [<FunctionName("MySampleFunction")>] let Run ([<TimerTrigger("0 */5 * * * *")>] myTimer: TimerInfo, context: ExecutionContext) = // 拼接函数目录路径 let functionDirectory = Path.Combine(context.FunctionAppDirectory, "MySampleFunction") // 后续可以用这个路径读取本地文件等操作 ()要是你的函数文件夹名和
FunctionName不一致,这种方式就不适用,得用下面的环境变量方式。直接读取环境变量
有些版本的进程内模型中,EXECUTION_CONTEXT_FUNCTIONDIRECTORY环境变量其实是存在的,可能你之前获取的方式有问题。可以用F#的标准方式读取:open System let functionDirectory = Environment.GetEnvironmentVariable("EXECUTION_CONTEXT_FUNCTIONDIRECTORY")本地测试时,确保
local.settings.json里没有覆盖这个变量;部署到Azure后,平台会自动注入该变量。
隔离进程(Isolated Worker)模型下的处理
如果是用隔离进程模型(依赖Microsoft.Azure.Functions.Worker包),ExecutionContext的结构确实做了调整,而且环境变量名称也变了,推荐这两种方法:
结合上下文访问器与宿主环境
通过依赖注入获取IFunctionExecutionContextAccessor和IHostEnvironment,拼接出函数目录:open Microsoft.Azure.Functions.Worker open Microsoft.Extensions.Hosting open System.IO type MyFunction(contextAccessor: IFunctionExecutionContextAccessor, hostEnv: IHostEnvironment) = [<Function("MyIsolatedFunction")>] member this.Run([<TimerTrigger("0 */5 * * * *")>] myTimer: TimerInfo) = let functionName = contextAccessor.FunctionContext.FunctionDefinition.Name let functionDirectory = Path.Combine(hostEnv.ContentRootPath, functionName) // 后续操作 ()读取隔离模型专属环境变量
隔离进程模型下,平台会自动设置AZURE_FUNCTIONS_FUNCTION_DIRECTORY环境变量,直接读取即可:open System let functionDirectory = Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_FUNCTION_DIRECTORY")
补充说明
你碰到的文档与实际不符的问题,是因为那篇文档针对的是较旧版本的WebJobs SDK,而Azure Functions近几年对进程内和隔离模型做了不少调整,环境变量和上下文属性都有更新。建议优先根据自己使用的运行模型选择对应的方案。
内容的提问来源于stack exchange,提问作者forki23

