나는 각각이 특정 작업 (비동기 중 일부)을 가지고 서로를 호출하는 방식을 많이 가지고 있는데, 모두 비동기식이므로 모든 것이 DOM에서 작동하기 때문에 (단 하나의 스레드 만 언제든지 DOM에 액세스해야한다).코드 실행을 지연시키는 가장 좋은 방법은 무엇입니까?
예를 들어: 이제
object A() {
/*...A() code 1...*/
var res = B();
/*...A() code 2 that uses res...*/
}
object B() {
/*...B code 1...*/
var res1 = C();
/*...B code 2 that uses res1...*/
var res2 = C();
/*...B code 3 that uses res2...*/
}
object C() {
/*...C code 1...*/
if (rnd.NextDouble() < 0.3) { // unpredictable condition
startAsyncStuff();
/*...C code 2 that uses async result above...*/
}
if (rnd.NextDouble() < 0.7) { // unpredictable condition
startOtherAsyncStuff();
/*...C code 3 that might use any/both async results above...*/
}
}
의 나는 방법 A를 (실행하고자하는 방법이 있다고 가정하자) 1000 배 가능한 한 빨리 (비동기 방법 그러나, 별도의 스레드 다른 모든를 실행할 수 있습니다 코드는 한 번에 하나씩 만 DOM에 액세스해야 함) 이상적으로 비동기 호출에 도달하면 A(), B() 및 C()에 대한 코드 실행이 일시 중지되므로 A()를 다시 호출 할 수 있습니다.
내가 할 수있는 두 가지 방법이 있습니다.
struct DeferResult {
public object Result;
public bool Deferred;
}
IEnumerator<DeferResult> A() {
/*...A() code 1...*/
var dres = B();
if (dres.Deferred) yield dres;
/*...A() code 2...*/
}
IEnumerator<DeferResult> B() {
/*...B code 1...*/
var dres1 = C();
if (dres1.Deferred) yield dres1;
/*...B code 2...*/
var dres2 = C();
if (dres2.Deferred) yield dres2;
/*...B code 3...*/
}
IEnumerator<DeferResult> C() {
/*...C code 1...*/
if (rnd.NextDouble() < 0.3) { // unpredictable condition
startAsyncStuff();
yield return new DeferResult { Deferred = true; }
/*...C code 2 that uses async result above...*/
}
if (rnd.NextDouble() < 0.7) { // unpredictable condition
startOtherAsyncStuff();
yield return new DeferResult { Deferred = true; }
/*...C code 3 that might use any/both async results above...*/
}
yield return new DeferResult { Result = someResult(); }
}
void Main() {
var deferredMethods = new List<IEnumerator<DeferResult>>();
for (int i = 0; i < 1000; i++) {
var en = A().GetEnumerator();
if (en.MoveNext())
if (en.Current.Deferred)
deferredMethods.Add(en);
}
// then use events from the async methods so when any is done continue
// running it's enumerator to execute the code until the next async
// operation, or until finished
// once all 1000 iterations are complete call an AllDone() method.
}
이 방법은 반복자에서 꽤 많은 오버 헤드를 가지고 있으며, 조금 더 많은 코드를 많이하지만 모든 : 하나는 반복자에 대한 모든 방법을 변경하여 I 일시 중지 및 실행을 재개 할 수 있습니다, 수율이다 하나의 스레드에서 실행되므로 DOM 액세스를 동기화 할 필요가 없습니다.
또 다른 방법은 스레드를 사용하는 것입니다 (1000 개의 동시 스레드는 나쁜 아이디어이므로 스레드 풀링의 일종을 구현할 수 있습니다). 그러나 이것은 비용이 많이 드는 DOM 액세스를 동기화해야합니다.
이러한 조건에서 코드 실행을 지연시키는 데 사용할 수있는 다른 방법이 있습니까? 이 작업을 수행하는 데 권장되는 방법은 무엇입니까?
나는 자물쇠가 그것을 할 것이라고 생각합니다. 그리고 폴링 작업의 경우 .Net 4.0 또는 ThreadPoll을 사용하는 경우 Task Parallel Library에서 빌드를 사용하십시오. –
동의하지만 설계 변경을 고려하고 싶을 수 있습니다. 왜 멀티 스레드를 원합니까? DOM에 대한 액세스를 직렬화하므로 한 번에 하나의 스레드 만 액세스 할 수 있으므로 스레드의 이점이 느슨해집니다. –