4

全部,

我正在将现有的 Worker Role 代码迁移到 Azure Web 作业。我正在尝试使用 WebJob SDK (1.0),以便与 Azure 网站完全集成。

我的困难是 JobHost 不能很好地处理超出其通常基于属性的调用选项(队列、Blob 等)的作业。

我已经有标准代码无法更改以收听 Azure 队列/主题等,因此我无法使用 WebJob 代码来执行此操作。

因此我需要使用 WebJob Call 方法:

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 中没有任何作用。

我的问题是我需要调用 host.RunAndBlock(); 停止工作退出,这很好,但是我需要运行一些清理处理。我无法使用 OnStop 方法重新调用“CallAsync”,因为主机已经被取消,所以我所能做的就是直接调用我的 OnStop 方法。不幸的是,我失去了通过提供的 TextWriter 类写入网站日志的能力。

我认为我需要一种让 JobHost 在 RunAndBlock 中调用我的方法的方法,这样我就可以拿起主机关闭时触发的取消令牌,然后执行我的清理代码....但似乎没有任何方式来做到这一点。

我有什么明显的失踪方式吗?JobHost 似乎在处理超出其规范的情况方面真的很差:(

4

2 回答 2

4

正如维克多所说,您可以使用Microsoft.Azure.WebJobs.WebJobsShutdownWatcher
这是 Amit 解决方案的实现:WebJobs Graceful Shutdown

所以我找到了一个解决方案:
在 Program.cs 中没有修改

class Program
{
    static void Main()
    {
        var host = new JobHost();
        host.Call(typeof(Startup).GetMethod("Start"));
        host.RunAndBlock();
    }
}

正常关机进入 Startup.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 循环之后,您还可以停止已启动的任务。

于 2015-07-01T05:36:11.203 回答
2

注意:我使用自己的 CallAsync,因为所有建议都是在使用库时使用 ConfigureAwait(false),但 JobHost 的内部没有这样做,所以我自己复制它的“调用”代码,但使用 ConfigureAwait。据我所知,取消令牌在 JobHost 中没有任何作用。

这是意料之中的,因为您正在传递自己的取消令牌,该令牌不会被任何人取消。当发送关闭通知或主机停止/处置时,Webjobs 取消令牌被取消。如果您想从 webjob 函数外部获取对取消令牌的引用,则必须将其保存在静态变量或类似变量中。

如果您想使用自己的取消令牌,您可以使用它Microsoft.Azure.WebJobs.WebJobsShutdownWatcher来获取关闭通知。

我的问题是我需要调用 host.RunAndBlock(); 停止工作退出,这很好,但是我需要运行一些清理处理。我无法使用 OnStop 方法重新调用“CallAsync”,因为主机已经被取消,所以我所能做的就是直接调用我的 OnStop 方法。不幸的是,我失去了通过提供的 TextWriter 类写入网站日志的能力。

对此没有开箱即用的解决方案,但您可以从正在运行的网络作业(如果有)调用清理功能。如果您需要在函数之外进行清理并且还需要日志记录,那么您只能控制台日志记录 - 写入控制台。日志将显示在 WebJobs 仪表板的 webJob 页面上。我是古玩,如果您需要在函数之外进行清理,那么场景是什么?

于 2015-01-06T08:44:12.463 回答