All,
我正在将现有的辅助角色代码迁移到 Azure Web 作业。我正在尝试使用 WebJob SDK (1.0),以便与 Azure 网站完全集成。
我的困难在于,JobHost 不能很好地处理它通常基于属性的调用选项(队列、Blob 等)之外的作业。
我已经有标准代码,我无法更改以侦听 Azure 队列/主题等,因此我无法使用 Web 作业代码来执行此操作。
因此,我需要使用 Web 作业调用方法:
var cancelTokenSource = new CancellationTokenSource();
var onStartMethod = typeof(Program).GetMethod("OnStart", BindingFlags.Static | BindingFlags.Public);
host.CallAsync(onStartMethod, cancelTokenSource.Token)
.ConfigureAwait(false)
.GetAwaiter()
.GetResult();
注意:我正在使用我自己的CallAsync,因为所有的建议都是在使用库时使用ConfigureAwait(false),但是JobHost的内部不这样做,所以我自己复制它的"调用"代码,但使用ConfigureAwait。据我所知,取消令牌在 JobHost 中没有任何作用。
我的问题是我需要打电话给主机。RunAndBlock();停止作业退出,这很好,但是我需要运行一些清理处理。我无法使用 OnStop 方法对"CallAsync"进行新调用,因为主机已被取消,所以我所能做的就是直接调用我的 OnStop 方法。不幸的是,我失去了通过提供的 TextWriter 类写入网站日志的能力。
我认为我需要的是 JobHost 在 RunAndBlock 中调用我的方法的方法,这样我就可以拿起主机关闭时触发的取消令牌,然后执行我的清理代码......但似乎没有任何办法可以做到这一点。
有没有明显的方式我错过了?JobHost似乎在处理超出其规范:(的场景方面非常差
正如victor所说,你可以使用Microsoft.Azure.WebJobs.WebJobsShutdownWatcher
这是 Amit 解决方案的实现:WebJobs Graceful Shutdown
所以我找到了这样做的解决方案:
程序没有修改.cs
class Program
{
static void Main()
{
var host = new JobHost();
host.Call(typeof(Startup).GetMethod("Start"));
host.RunAndBlock();
}
}
正常关闭进入启动.cs :
public class Startup
{
[NoAutomaticTrigger]
public static void Start(TextWriter log)
{
var token = new Microsoft.Azure.WebJobs.WebJobsShutdownWatcher().Token;
//Shut down gracefully
while (!token.IsCancellationRequested)
{
// Do somethings
}
}
}
在 while 循环之后,您还可以停止已启动的任务。
注意:我正在使用我自己的CallAsync,因为所有的建议都是在使用库时使用ConfigureAwait(false),但是JobHost的内部不这样做,所以我自己复制它的"调用"代码,但使用ConfigureAwait。据我所知,取消令牌在 JobHost 中没有任何作用。
这是意料之中的,因为您正在传递自己的取消令牌,该令牌未被任何人取消。发送关闭通知或停止/释放主机时,将取消 Web 作业取消令牌。如果要从 webjob 函数外部获取对取消令牌的引用,则必须将其保留在静态变量或类似变量中。
如果要使用自己的取消令牌,可以使用Microsoft.Azure.WebJobs.WebJobsShutdownWatcher
来获取关闭通知。
我的问题是我需要打电话给主机。RunAndBlock();停止作业退出,这很好,但是我需要运行一些清理处理。我无法使用 OnStop 方法对"CallAsync"进行新调用,因为主机已被取消,所以我所能做的就是直接调用我的 OnStop 方法。不幸的是,我失去了通过提供的 TextWriter 类写入网站日志的能力。
没有现成的解决方案,但您可以从正在运行的 Web 作业(如果有)调用清理函数。如果您需要在函数之外进行清理,并且还需要日志记录,那么您只能使用控制台日志记录 - 写入控制台。日志将显示在 Web 作业仪表板的 Web 作业页面上。我很好奇,如果您需要在函数之外进行清理,情况是什么?