루프

2016-12-22 8 views
1

내가 구조의이 종류 가지고 결국 몇 가지 코드를 최적화하기 위해 노력 foreach는 중첩 된 익명 함수를 번역 :루프

StaticMethod(propA,() => 
{ 
    StaticMethod(propB,() => 
    { 
     StaticMethod(propC,() => 
     { 
      // Write line in console here to say it's done. 
     }); 
    }); 
}); 

을 그리고 어쩌면 일부 foreach 또는 해당를 단순화 할 수있는 방법이 있어야한다 생각 간단한 for 루프, 다음과 같은 내용 :

foreach (var prop in props) // consider that `props` can be iterated over 
{ 
    // Here I don't know how to chain everything... 
} 

이 작업을 수행 할 수 있습니까? 이 문제를 해결하려면 StaticMethod을 수정해야합니까? 루프만으로는 충분하지 않을 수도 있지만 예제를 1000 개의 중첩 된 함수로 확장하면 반복이 필요합니다.

static void StaticMethod(Prop prop, Action done) 
{ 
    // Some code here 
    someDispatcher.BeginInvoke(() => { 
     // More code here 
     done(); 
    }); 
} 
+1

예제가 너무 일반적으로 보입니다. 정적 메서드가'foreach'에 필수적인'IEnumerable'에 대해 작동하는지 알 수 없습니다. – BradleyDotNET

+0

요구 사항이 명확하지 않습니다. 현재의 소품 만 확인하면 다음 소품을 처리하고 싶습니까? 람다 사용의 요점은 무엇입니까? 코드를 좀 더 혼란스럽게하는 경우를 제외하고는 아무 것도하지 않습니다. – SledgeHammer

+0

@BradleyDotNET 너무 광범위 : 답변이 너무 많습니다. 1 ~ 2 점을 지적하여 실제로 얼마나 광범위하게 볼 수 있습니다. 좋은 답변이 너무 길어서 Servy는 적절한 형식으로 응답하고 내가 요구 한 것보다 더 많은 세부 사항을 추가했습니다. 이것은 1 년이 지나서 꽤 화가났다. 나는 OP와 2를 편집했다. 편집은 직접 또는 주석으로 제안하지 않았다. 또한 내 질문에 예/아니오로 질문 할 수 있다고 명시되어 있습니다 ... – Mat

답변

4

이 비동기의 콜백 기반 모델과 매우 어려운 문제가 참으로 :

여기 StaticMethod의 개념입니다. StaticMethodTask 기반 비동기 모델로 변환하면 이 더 간단 해집니다. StaticMethod이 자신의 메서드 인 경우 Task 기반 모델을 사용하여 다시 작성하는 것이 가장 이상적입니다. 끝나면 Task을 반환하는 대신 콜백을 사용하지 않고 메서드가 아니라면 ' 그것을 변경하면 Task 기반 모델을 사용하는 래퍼를 만들 수 있습니다. 당신은 단순히 TaskCompletionSource 사용하십시오 Task 기반 방법으로 콜백을 기반 방법을 변환하려면 : 우리가 async 방법을 쓸 수 있는지 지금 우리가 가지고

public static Task StaticMethodAsync(object a) 
{ 
    var tcs = new TaskCompletionSource<bool>(); 
    StaticMethod(a,() => tcs.SetResult(true)); 
    return tcs.Task; 
} 

을 그 props을 반복 차례로 각 비동기 메서드를 호출 :

을 아래 볼 수 있듯이, 당신은 할 수있는 콜백 모델을 유지하지만, 동시에 당신이 정말로이 문제를 해결하려면 경우
foreach (var prop in props) 
{ 
    await StaticMethodAsync(prop); 
} 
// Write line in console here to say it's done. 

, 그것은 읽을 훨씬 더 어려워 이해 단계별 실행 :

public static void Foo(object[] props, Action callback) 
{ 
    int i = -1; 
    Action innerCallback = null; 
    innerCallback =() => 
    { 
     i++; 
     if (i < props.Length) 
     { 
      StaticMethod(props[i], innerCallback); 
     } 
     else 
     { 
      callback(); 
     } 
    }; 
    innerCallback(); 
} 
+2

질문에 비동기 처리가 표시되지 않습니다 ...나에게 그것은 어색한 건축 자 패턴처럼 보인다. 그러나 당신은 옳을 수있다. –

+0

@AlexeiLevenkov 델리게이트는 아무것도 반환하지 않으므로 '액션'입니다. 값을 계산할 때이 값을 사용한다면 확실합니다. 그러나 액션이기 때문에 델리게이트가 돌아 오기 전에 델리게이트를 호출하는 경우에도이 변환이 유효합니다. 그리고 comment'// 여기에 콘솔을 작성하여 완료라고 말하십시오. '는 델리게이트가 프로세스의 완료를 나타내는 콜백이되는 매우 매력적인 사례입니다. – Servy

+0

@Servy 언뜻 보면 유망 해 보입니다. 내가 게시 할 때 그 코드를 포함해야한다고 생각하기 때문에 제 편집을 참조하십시오. 'Task'로 당신의 솔루션을 구현하려고 할 것입니다! – Mat