0

我正在向未充分利用的 Azure Web 角色添加一个简单的工作进程。为了可靠性/正常运行时间,我在 2 个实例上运行了这个 Web 角色。这个工作进程将被设置为休眠大约 5 分钟,然后再执行一个操作,然后再次休眠。通过将此工作进程添加到 Web 角色,它将在多个实例上运行,并且它们都将尝试同时执行相同的操作。通常这个问题可以通过使用队列来解决,但我不需要任何复杂的东西。我只是为了防止两个实例完全同步。

我的想法是将 thread.sleep 从硬编码的等待时间更改为随机等待时间,如下所示:

    Public Overrides Sub Run()

    Trace.WriteLine("Worker Role entry point called.", "Information")

    While (True)
        Dim r As New Random
        Dim wait As Integer = r.Next(60000, 600000)
        Dim Minutes As Decimal = wait / 60000
        Thread.Sleep(wait)
        Trace.WriteLine(String.Format("Worker Role - Triggered on {0:f}.  Waited {1:N2} Minutes.", Now(), Minutes), "Information")
    End While

    End Sub

实例 0 的输出:
信息:调用了工作角色入口点。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 9:37 触发。等了 7.71 分钟。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 9:41 触发。等了 4.25 分钟。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 9:49 触发。等了 7.87 分钟。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 9:53 触发。等了 4.77 分钟。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 10:03 触发。等了 9.91 分钟。

实例 1 的输出:
信息:调用了 Worker Role 入口点。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 9:38 触发。等了 9.47 分钟。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 9:44 触发。等了 6.15 分钟。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 9:48 触发。等了 3.41 分钟。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 9:49 触发。等了 1.63 分钟。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 9:58 触发。等了 8.26 分钟。
信息:工人角色 - 于 2012 年 8 月 27 日星期一上午 10:01 触发。等了 3.14 分钟。

这个计划是否有我没有看到的缺陷?感谢您的输入!

4

2 回答 2

4

好吧,要回答您的名义问题,这并不能保证他们俩同时做某事。但这肯定会降低这种可能性。

也就是说,使用实际的并发控制机制不必“精心设计”。来自http://blog.smarx.com/posts/simple-scheduling-in-windows-azure

AutoRenewLease.DoEvery(blob, TimeSpan.FromMinutes(5), () => {
    Trace.WriteLine("Doing stuff at {0:R}", DateTimeOffset.UtcNow);
});

为什么不这样做呢?它以 NuGet 包的形式提供,它可以缩短您的代码。:-)

于 2012-08-27T20:55:00.777 回答
1

这是您在拥有多个辅助角色实例时可能面临的典型问题。并且解决方案非常简单,使用 Steve Marx 的WazStorageExtensions库。该库允许您编写如下代码:

using (var arl = new AutoRenewLease(leaseBlob))
{
    if (arl.HasLease)
    {
        // inside here, this instance has exclusive access
    }
} // lease is released here

从示例中可以看出,如果特定实例具有租约,则可以独占访问您正在执行的任何操作。

该库使用 blob 租约,您可以将其与 C# 中的 lock 关键字进行比较。但是锁定 blob 允许您锁定不同的进程甚至不同的实例。当时只有一个实例可以租用一个 blob,这意味着您可以确保一个进程不会同时在多个实例上运行。而且您仍然可以使用随机计时器来保持进程运行,而不必担心并发性。

于 2012-08-27T20:53:22.910 回答