8

受信リクエストごとに2つの別々のWebサービスを呼び出し、後処理を実行して結果を返すWebApiがあります。

最初の Web サービス呼び出しはローカルに 1 時間キャッシュされ、この中のデータによって 2 番目の Web サービスへのクエリが決定されます。2 番目の Web サービスは、着信要求ごとに呼び出されます。2 番目の要求が行われた後、各結果はビジネス ロジックで処理され、クライアントの応答に返されます。

2 番目の Web サービスへの呼び出しは、await キーワードを許可しないサード パーティの DLL を使用しているため、非同期にすることはできません。私が行ったことは、2 番目の Web サービス呼び出しと後処理を、コントローラーから呼び出される 1 つの非同期関数にラップすることです。

// /api/controller/news?key=a&state=b
public async Task<HttpResponseMessage> GetNews(string key, string state)
    {
         // call to first webservice if not in cache
         if (JsonConfig != null && JsonConfig.Configuration.NewsQuery.ContainsKey(key))
        { 
            var results = await SearchProxyProvider.Search(filters.All, filters.Any, filters.None, filters.Sort, 100, 0, true, state, true);
            int totalCount = results.TotalCount;

            return Request.CreateResponse(HttpStatusCode.OK, results);
        }
    }


// Helper class method
public async Task<ItemCollection<Item>> Search(List<FieldValuePair> allFilters, List<FieldValuePair> anyFilters, List<FieldValuePair> noneFilters, SortedFieldDictionary sortBy, int pageSize = 100, int pageNumber = 0, bool exact = true, string stateFilter = null, bool getAllResults = true)
        {
            // call to 2nd api
            search = SomeApi.Search(allFilters, anyFilters, noneFilters, pageSize, pageNumber, exact,
                                               sortBy, null, WebApiConstant.Settings.CustomFields, true);

            // post processing on search results
            return search;
        }

最初の Web サービスの呼び出しはローカルにキャッシュされるため、これを非同期にするメリットはあまりありません。

このアプローチが完全に間違っているか正しいかを確認したいだけです。

4

2 に答える 2

8

最初の Web サービス呼び出しはローカルに 1 時間キャッシュされ、この中のデータによって 2 番目の Web サービスへのクエリが決定されます。

AsyncLazy<T>(たとえば、私のブログから)いくつかのトリックを実行して、代わりにキャッシュすることができます。これにより、要求が (非同期で) 更新を待機する方法が提供され、同時要求の数に関係なく、データを更新する必要があるときに Service1 を複数回ヒットすることはありません。

2 番目の Web サービスへの呼び出しは、await キーワードを許可しないサード パーティの DLL を使用しているため、非同期にすることはできません。

それは残念です。それを修正するために彼らに頼ってください。:)

私が行ったことは、2 番目の Web サービス呼び出しと後処理を、コントローラーから呼び出される 1 つの非同期関数にラップすることです。

それには意味がありません。コンパイラは、「非同期」メソッドが実際には同期的であることを警告します。

同期の場合は、同期的に呼び出すだけです。サーバー側では、それをラップしても意味がありませんTask.Run

月曜日のThatConferenceで行った "Async on the Server" の講演からいくつかのスライドを入手できます。(非同期リクエストがどのように処理されるか、および「偽の非同期」メソッドがサーバー側で役に立たない理由のアニメーションがあります)。

于 2013-08-14T23:05:58.040 に答える
0

関数 Search を完全に非同期にするには、SomeApi.Search の呼び出しを別のタスクにラップしてから待機します。また、最初の関数のコードをタスクにラップすることも検討してください。負荷の見積もりでは、キャッシュの検証もボトルネックになる可能性があります。

// call to 2nd api
var search = await Task.Factory.StartNew(()=> {return Some Api.Search(allFilters, anyFilters, noneFilters, pageSize, pageNumber, exact,
                                               sortBy, null, WebApiConstant.Settings.CustomFields, true);});
于 2013-08-14T14:59:08.893 に答える