4

Azure WebJobs を初めて使用するので、基本的な質問があります。WebJob としてデプロイされたコンソール アプリがあります。本来、コンソール アプリは多くの静的変数を使用ます。以下に示すように、いくつかのローカル静的変数があります。複数のスレッドが WebJob によってこれらの変数を同時に更新すると、問題が発生しますか?

class Program
{
    private static MyService _service;
    private static int _counter;

    static void Main()
    {
      ...
    }

    private static void Method1() { .... }
}
4

6 に答える 6

4

質問にタグを付けたのでazure-webjobs-sdk、SDK について数日前に別の質問があったことを覚えています。Web ジョブが SDK を使用しており、トリガーされた関数を並行して実行しているという事実が原因でマルチスレッドが発生していると思います。

私の答えの最初の部分は、必ずしも Web ジョブに関連するものではありません。

class Program
{
    private static MyService _service;
    private static int _counter;

    private static readonly object _lock = new object();

    // The 3 blocks of code are thread safe by themselves
    // but put together, there is no guarantee. Avoid
    // multiple locks if you can
    private static void Method1() 
    {
        // 1. You can use a lock 
        lock(_lock)
        {
            // All the code here will be executed by a single thread. 
            // If another thread tries to get the lock, it will have
            // to wait until the lock is released

            _service.DoSomething();
        }

        // 2. For atomic operations you can use Interlocked
        Interlocked.Increment(ref _counter);

        // 3. For conditional locking
        if (_service.SomeBooleanProperty)
        {
            lock(_lock)
            {
                // Check again to see the condition still holds
                // because it might have changed between the
                // execution of the first if and the lock
                if (_service.SomeBooleanProperty)
                {
                    // Execute the non thread safe code
                }
            }
        }
    }
}

Interlockedクラスへの参照

今、私は WebJobs SDK について話している:

処理の並行性を制御する場合は、プロパティを設定できQueue.BatchSizeます。デフォルトでは 16 です。1 に設定すると、すべてが順次実行されます。こちらのリファレンスを参照してください。複数インスタンスの同時実行 (同じジョブの複数のインスタンス) で同時実行の問題が発生している場合は、BLOB リースが最適です。

于 2014-10-04T17:11:17.303 に答える
2

バッチ サイズを (Azure WebJob コンテキスト内で) 1 つに制限する場合は、次のようにします。

static void Main()
        {
            InitializeStorage();
            JobHostConfiguration config = new JobHostConfiguration();
            config.Queues.BatchSize = 1; // the Azure default is 16
            var host = new JobHost(config);
            host.RunAndBlock();
        }

詳細については、この記事の「キューを使用した並列実行」ビットを参照してください。

于 2015-11-10T12:48:47.563 に答える
2

いいえ、コンソール アプリケーションで特にマルチスレッド コードを記述しない限り、そうではありません。WebJob が Azure で呼び出されると、独自のプロセスが取得されます。たとえば、ConsoleTestApp.exe という Web ジョブのプロセス エクスプローラーからのスクリーン キャプチャを次に示します。PID は、Web サイトが実行されている W3WP プロセスとは別のものであることに注意してください。

ここに画像の説明を入力

于 2014-10-04T15:57:54.227 に答える
1

ジョブの複数のインスタンスは、同じアプリ ドメイン内の異なるスレッドで実行されます。つまり、静的変数はスレッド セーフではありません。

これは簡単にテストできます。TextWriterTraceListenerwithを登録し、複数のジョブからSystem.Diagnostics.Trace.Listenerswith で書き込みTrace.WriteLine、最後に削除すると、クロストークが発生するのもこのためです。

本来、コンソール アプリは多くの静的データを使用します

コンソール アプリは、本質的に静的変数の使用を強制されることはなく、Web ジョブもそうではありません。クラスのインスタンスを作成して何らかの処理を行い、そのクラスのメソッドを呼び出します。これの非常に基本的な例を次に示します。

class Program
{
    public int Start(string[] args)
    {
        // You can use non-static variables here
        Console.WriteLine("There were {0} arguments.", args.Length);
        return 0;
    }

    static int Main(string[] args)
    {
        return new Program().Start(args);
    }
}
于 2015-10-28T17:26:40.573 に答える
1

「スレッド」とはどういう意味ですか?

コードによって生成された実際のスレッドはありますか? (サンプルコードには何も表示されていません。) 実際、静的変数にアクセスするときに問題が発生します。他のマルチスレッド コードと同様です。

しかし、実際にはスレッドを意味するのではなく、実行中のジョブの個別のインスタンスを意味していると思います。これらは個別のプロセスであるため、それぞれに静的変数の独自のコピーがあります。お互いのメモリにアクセスすることさえできません。

他のジョブと同様に、Web ジョブは単なるアプリケーションであることに注意してください。魔法はありません。同じアプリケーションを複数回実行する場合、各インスタンスには静的変数用に独自のメモリが割り当てられます。

于 2014-10-04T16:02:04.510 に答える
0

ASP.Net リクエスト処理モデルと同様に、SDK による Web ジョブの処理を確認する必要があります。eash リクエストが異なるスレッドで処理される ASP.Net のように、WebJobs SDK では、ジョブのすべての呼び出しが異なるスレッドで発生します。Web ジョブによって操作される静的変数がある場合、問題が発生する可能性があります。アプリケーションに WebJob が 1 つしかない場合は、batchsize を 1 に設定することで問題を回避できます。これにより、一度に 1 つのジョブのみが実行され、静的変数を操作できるようになります。

ただし、複数の Web ジョブ関数があり、それらすべてが同じ静的変数を使用している場合、すべてのタイプから少なくとも 1 つの呼び出しが同時に実行され、それらすべてが同じ静的変数を操作するため、バッチ サイズは役に立ちません。

静的変数を使用し、メモリ リークがある従来のコード ベースにも同じ問題があります。webjobs exe から実際の処理を行う別の exe を生成する予定です。子 exe は、ジョブに必要な webjob exe からのパラメーターを受け入れるだけで、単一のジョブの完了後にそれ自体を閉じます。そのため、レガシー コードのメモリ リークや静的変数によって問題が発生することはありません。webjobs exe は、子 exe から console.writes をリッスンし、同じストリームに書き込むだけで、webjobs ポータルに表示されます。

于 2015-07-20T15:18:22.857 に答える