質問

Webサービスメソッドで非同期処理を実行しようとしています。次のAPI呼び出しがあるとしましょう: http://www.example.com/api.asmx

そしてメソッドは GetProducts()と呼ばれます。

このGetProductsメソッドは、何かを行う(たとえば、データベースからデータを取得する)後、結果を返す直前に、非同期を行う(たとえば、メールを送信する)

これが私がやったことです。

[WebMethod(Description = "Bal blah blah.")]
public IList<Product> GetProducts()
{
    // Blah blah blah ..
    // Get data from DB .. hi DB!
    // var myData = .......
    // Moar clbuttic blahs :)  (yes, google for clbuttic if you don't know what that is)

    // Ok .. now send me an email for no particular reason, but to prove that async stuff works.
    var myObject = new MyObject();
    myObject.SendDataAsync();

    // Ok, now return the result.
    return myData;
    }
}

public class TrackingCode
{
    public void SendDataAsync()
    {
        var backgroundWorker = new BackgroundWorker();
        backgroundWorker.DoWork += BackgroundWorker_DoWork;
        backgroundWorker.RunWorkerAsync();
        //System.Threading.Thread.Sleep(1000 * 20);
    }

    private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        SendEmail();
    }
}

今、このコードを実行すると、メールは送信されません。 Thread.Sleep ..のコメントを外すと、電子メールが送信されます。

では...なぜバックグラウンドワーカースレッドが破棄されるのですか?親スレッドに依存していますか?これは、asp.net Webアプリでバックグラウンドまたはフォークスレッドを行うべき間違った方法ですか?

役に立ちましたか?

解決

BackgroundWorker は、たとえば親和性の理由で、UI *スレッドに同期して戻す必要がある場合に役立ちます。この場合、単に ThreadPool を使用するだけで十分である(そしてより単純になる)と思われます。ボリュームが大きい場合、プロデューサー/コンシューマーキューを使用すると、より適切な調整が可能になる場合があります(したがって、スレッドにdrれません)。

public void SendDataAsync()
{
    ThreadPool.QueueUserWorkItem(delegate
    {
        SendEmail();
    });
}

また-寝ることで何を達成したいのかよくわかりませんか?これはスレッドを結び付けるだけです(CPUは使用しませんが、どちらもうまくいきません)。手入れをしますか?実際のWebページを一時停止しているように見えます(つまり、スリープは電子メールスレッドではなく、Webページスレッドで発生します)。ここで何をしようとしていますか?

* =実際には、同期コンテキストが設定されているものを使用します

他のヒント

再生産者/消費者。基本的には、何らかの種類のスロットルを維持するだけの価値があります。最も単純なレベルでは、 Semaphore を(通常の ThreadPool と一緒に)使用して、既知の量の作業に制限することができます(スレッドプールの飽和を回避するため)。しかし、生産者/消費者キューはおそらくより効率的で管理されます。

Jon Skeetにはこのようなキューがありますこちら CustomThreadPool )。あなたが望むなら、おそらくそれについていくつかのメモを書くことができます。

つまり、外部のWebサイトを呼び出している場合、ネットワークIO /完了ポートで多くの待機が発生する可能性が非常に高くなります。そのため、スレッドの数をわずかに増やすことができます...明らかに(対照的に)作業がCPUにバインドされている場合、CPUコアよりも多くのスレッドを持つことは意味がありません。

20秒後に、BackgroundWorkerインスタンスが参照を持たない(スコープ外になった)ためにガベージコレクションされる可能性があるため、破棄される可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top