簡體   English   中英

異步WCF查詢最后一步

[英]Asynchronous WCF Query Final step

我正在嘗試學習如何實現異步模式來並發查詢多個wcf服務,但是不知道如何檢查所有並發調用是否完整。 我有一個執行異步操作的類,然后在操作完成時將其添加到列表中:

   public static class ODataAsync
    {
        static DataServiceContext ServiceContext;
        static List<DynamicEntity> Results = new List<DynamicEntity>(); 

        private static void GetAsync(string serviceUri, NameValueCollection queryOptions, IAuthenticationScheme authenticationScheme)
        {
            string baseUri;
            string entitySet;
            string entityKey;
            string queryString;
            ValidateServiceUri(serviceUri, out baseUri, out entitySet, out entityKey, out queryString);
            string resource = !string.IsNullOrEmpty(entityKey) ? entitySet + "(" + entityKey + ")" : entitySet;

            DataServiceContext context = new DataServiceContext(new Uri(baseUri));
            context.IgnoreMissingProperties = true;

            ServiceContext = context; 

            DataServiceContextHandler handler = new DataServiceContextHandler(authenticationScheme);
            handler.HandleGet(context);

            DataServiceQuery<EntryProxyObject> query = context.CreateQuery<EntryProxyObject>(resource);

            NameValueCollection options = HttpUtility.ParseQueryString(queryString);
            options.Add(queryOptions);

            foreach (string key in options.AllKeys)
            {
                query = query.AddQueryOption(key, options[key]);
            }

            try
            {
                query.BeginExecute(GetAsyncComplete, query);
            }
            catch (DataServiceQueryException ex)
            {
                throw new ApplicationException("An error occurred during query execution.", ex); 
            }
        }

        private static void GetAsyncComplete(IAsyncResult result)
        {
            QueryOperationResponse<EntryProxyObject> response = 
                ((DataServiceQuery<EntryProxyObject>)result).EndExecute(result) as QueryOperationResponse<EntryProxyObject>; 

            IList<dynamic> list = new List<dynamic>(); 

            foreach (EntryProxyObject proxy in response)
            {
                DynamicEntity entity = new DynamicEntity(proxy.Properties);
                Results.Add(entity);
            }

            while (response.GetContinuation() != null)
            {
                Uri uri = response.GetContinuation().NextLinkUri;

                response = ServiceContext.Execute<EntryProxyObject>(uri) as QueryOperationResponse<EntryProxyObject>;

                foreach (EntryProxyObject proxy in response)
                {
                    DynamicEntity entity = new DynamicEntity(proxy.Properties);
                    Results.Add(entity);
                }
            }
        }    
    }

我的兩個問題是:

1)如何確保僅在所有並發調用完成后才獲得列表結果? 例如,如果在循環中調用GetAsync(),啟動多個並發進程,則需要確保在將數據從“列表結果”中取出之前,它們都已完成。

2)我可以在GetContinuation()調用內使用BeginExecute()並遞歸使用與回調函數相同的方法GetAsyncComplete()嗎? 否則會創建大量線程並實際上減慢速度。

謝謝。

看一下靜態的WaitHandle.WaitAll(WaitHandle [] waitHandles)方法。 該頁面上有一個很棒的代碼示例。

通常,任何實現異步模式的類都將定義以下形式的方法:

IAsyncResult BeginXXX(AsyncCallback callback, Object state);

Result EndXXX(IAsyncResult asyncResult);

調用BeginXXX異步調用該方法,而調用EndXXX強制當前線程等待,直到異步方法完成。

要進行多個異步調用,您所需要做的就是根據需要多次調用BeginXXX ,然后調用WaitHandle.WaitAll(...) ,將IAsyncResult.AsyncWaitHandle傳遞給您要等待的所有調用。

要回答第二個問題,是的,您可以遞歸使用GetAsynComplete 賦予BeginXXX調用的state參數用於標識請求,可以通過IAsyncResult.UserState屬性進行訪問-因此您可以將請求與響應進行匹配。

這是否是一件好事更主觀。 通常,異步調用通過線程池進行,因此一次創建大量異步調用會耗盡可用線程,此后,新調用將排隊,直到線程可用為止。 在線程之間進行切換會產生一些開銷,但是與同步執行所花費的時間相比,這可能並不重要(除非您擁有大量線程)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM