문제

네 가지 웹 요청의 데이터를 단일 항목 목록으로 결합해야 하는 페이지가 있습니다.현재 저는 이들을 순차적으로 실행하고 단일 목록에 추가한 다음 해당 목록을 내 반복 레이아웃에 바인딩하고 있습니다.

그러나 나는 이 네 가지 웹 요청을 비동기식으로 호출하여 동시에 실행하고 로드 시간을 절약할 수 있기를 원합니다.불행하게도 내가 본 모든 비동기 튜토리얼과 기사는 처리를 계속하기 위해 완성된 핸들러를 사용하여 단일 요청을 처리합니다.

각 결과가 단일 목록에 입력되어야 한다는 점을 염두에 두고 4개(이는 더 늘어날 수도 있음)를 동시에 수행하려면 어떻게 해야 합니까?

많은 감사합니다!

편집하다:내가 하고 있는 일에 대한 간단한 예:

var itm1 = Serialize(GetItems(url1));
list.AddRange(itm1);
var itm2 = Serialize(GetItems(url2));
list.AddRange(itm2); 

string GetItems(string url)
{
     var webRequest = WebRequest.Create(url) as HttpWebRequest;
     var response = webRequest.GetResponse() as HttpWebResponse;

     string retval;
     using (var sr = new StreamReader(response.GetResponseStream()))
     { retval = sr.ReadToEnd(); }
     return retval;
} 
도움이 되었습니까?

해결책

최종 데이터는 네 가지 요청 모두의 결과에 따라 달라지므로 이는 매우 간단합니다.

당신이 할 수 있는 일은 각각 적절한 웹 메소드를 가리키는 4개의 비동기 대리자를 만드는 것입니다.그들 모두에 대해 BeginInvoke를 수행하십시오.그런 다음 WaitHandle을 사용하여 모두 기다립니다.귀하의 경우에는 웹 메소드가 처리되는 동안 계속 진행하고 싶지 않고 모든 웹 메소드 실행이 완료될 때까지 기다리므로 콜백을 사용할 필요가 없습니다.

모든 웹 메소드가 실행된 후에만 wait 문 이후의 코드가 실행됩니다.여기서 4개의 결과를 결합할 수 있습니다.

제가 여러분을 위해 개발한 샘플 코드는 다음과 같습니다.

class Program
    {
        delegate string DelegateCallWebMethod(string arg1, string arg2);

        static void Main(string[] args)
        {
            // Create a delegate list to point to the 4 web methods
            // If the web methods have different signatures you can put them in a common method and call web methods from within
            // If that is not possible you can have an List of DelegateCallWebMethod
            DelegateCallWebMethod del = new DelegateCallWebMethod(CallWebMethod);

            // Create list of IAsyncResults and WaitHandles
            List<IAsyncResult> results = new List<IAsyncResult>();
            List<WaitHandle> waitHandles = new List<WaitHandle>();

            // Call the web methods asynchronously and store the results and waithandles for future use
            for (int counter = 0; counter < 4; )
            {
                IAsyncResult result = del.BeginInvoke("Method ", (++counter).ToString(), null, null);
                results.Add(result);
                waitHandles.Add(result.AsyncWaitHandle);
            }

            // Make sure that further processing is halted until all the web methods are executed
            WaitHandle.WaitAll(waitHandles.ToArray());

            // Get the web response
            string webResponse = String.Empty;
            foreach (IAsyncResult result in results)
            {
                DelegateCallWebMethod invokedDel = (result as AsyncResult).AsyncDelegate as DelegateCallWebMethod;
                webResponse += invokedDel.EndInvoke(result);
            }
        }


        // Web method or a class method that sends web requests
        public static string CallWebMethod(string arg1, string arg2)
        {
            // Code that calls the web method and returns the result

            return arg1 + " " + arg2 + " called\n";
        }

    }

다른 팁

각 요청을 자신의 별도 스레드에서 시작한 다음 결과를 목록에 추가하는 것은 어떻습니까?

다음 코드를 테스트 할 수 있습니다.

parallel.invoke (() => {
// TODO 요청을 실행합니다 ...});

참조 평행 연장이 필요합니다.http://msdn.microsoft.com/en-us/concurrency/bb896007.aspx

@Josh : 4 (잠재적으로 더 많은) 비동기 요청을 보내고 응답을 추적하는 것에 대한 질문과 관련하여 (예 : 목록에 공급하기위한). 4 개의 요청과 4 개의 응답 핸들러를 작성할 수 있지만 더 많은 요청이 있으므로 비동기 루프를 작성할 수 있습니다. 고전적인 루프는 초기, 조건 및 증분으로 만들어집니다. 고전적인 루프를 while 루프로 분해하고 여전히 동등하게 될 수 있습니다. 그런 다음 while 루프를 재귀 함수로 만듭니다. 이제 비동기식으로 만들 수 있습니다. 여기에 샘플 스크립트를 넣었습니다 http://asynchronous.me/ . 귀하의 경우 옵션에서 For Loop을 선택하십시오. 요청을 순서대로 전송하려면, 즉 이전 응답 (request1, response1, request2, response2, request3, response3 등) 후 하나의 요청을 원하시면 직렬 통신 (예 : 순차적)을 선택하지만 코드가 조금 더 있습니다. 뒤얽힌. 반면에 응답이 수신 된 순서 (임의 순서)에 신경 쓰지 않으면 병렬 통신 (즉 동시)을 선택하면 코드가 더 직관적입니다. 두 경우 모두, 각 응답은 식별자 (간단한 정수)의 해당 요청과 연관되므로 모두 추적 할 수 있습니다. 이 사이트는 샘플 스크립트를 제공합니다. 샘플은 JavaScript로 작성되었지만 모든 언어에 적용됩니다. 스크립트를 언어 및 코딩 선호도에 적응하십시오. 해당 스크립트를 사용하면 브라우저가 4 개의 요청을 비동기 적으로 보내며 식별자에 의해 응답이 해당하는 요청을 추적 할 수 있습니다. 도움이 되었기를 바랍니다. /Thibaud Lopez Schneider

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top