12

カスタムコードに基づくRESTサービスをWebAPIに変換するという課題に直面しています。このサービスには大量のリクエストがあり、読み込みに時間がかかる可能性のあるデータを処理しますが、読み込まれるとキャッシュして、すべての着信リクエストを処理するために使用できます。以前のバージョンのサービスには、データのロードとキャッシュへの取得を担当する1つのスレッドがありました。IISがワーカースレッドを使い果たすのを防ぐために、クライアントはキャッシュの準備ができるまで「後で戻ってくる」応答を受け取ります。

Web APIについての私の理解では、タスクを操作することによって非同期動作が組み込まれているため、要求の数は、保持されている物理スレッドの数に直接関係しません。

このサービスの新しい実装では、キャッシュの準備ができるまでリクエストを待機させてから、有効な応答を行うことを計画しています。説明のために、コードの非常に大まかなスケッチを作成しました。

public class ContactsController : ApiController
{
    private readonly IContactRepository _contactRepository;

    public ContactsController(IContactRepository contactRepository)
    {
        if (contactRepository == null) 
            throw new ArgumentNullException("contactRepository");
        _contactRepository = contactRepository;
    }

    public IEnumerable<Contact> Get()
    {
        return _contactRepository.Get();
    }
}

public class ContactRepository : IContactRepository
{
    private readonly Lazy<IEnumerable<Contact>> _contactsLazy;

    public ContactRepository()
    {
        _contactsLazy = new Lazy<IEnumerable<Contact>>(LoadFromDatabase, 
            LazyThreadSafetyMode.ExecutionAndPublication);
    }

    public IEnumerable<Contact> Get()
    {
        return _contactsLazy.Value;
    }

    private IEnumerable<Contact> LoadFromDatabase()
    {
        // This method could be take a long time to execute.
        throw new NotImplementedException();
    }
}

コードの設計にあまり価値を置かないでください。コードは問題を説明するためだけに作成されており、実際のソリューションで行った方法ではありません。IContactRepositoryはIoCコンテナーにシングルトンとして登録され、コントローラーに注入されます。Lazy with LazyThreadSafetyMode.ExecutionAndPublicationは、最初のスレッド/リクエストのみが初期化コードを実行していることを確認します。次のリクエストは、初期化が完了するまでブロックされます。

Web APIは、初期化が完了するのを待っている1000の要求を処理できますか?このレイジーにヒットしない他の要求はサービス中であり、IISがワーカースレッドを使い果たすことはありませんか?

4

1 に答える 1

10

アクションから戻るTask<T>と、コードがバックグラウンドスレッド(ThreadPool)で実行され、IISスレッドが解放されます。だからこの場合、私は変更します

public IEnumerable<Contact> Get()

public Task<IEnumerable<Contact>> Get()

開始したタスクを返すことを忘れないでください。そうしないと、スレッドはただ座って何もしません。

遅延実装は便利ですが、WebAPIの動作とはほとんど関係がありません。だから私はそれについてコメントするつもりはありません。怠惰の有無にかかわらず、タスクベースのリターンタイプは、長時間実行される操作に進む方法です。

私はこれについて2つのブログ投稿を持っています。これはおそらくあなたに役立つでしょう:ここここ

于 2012-04-16T12:46:42.647 に答える