2011-08-09 5 views
9

특정 대리인이 어떤 스레드에서 실행될 수 있는지를 추상화 할 수있는 방법이 있습니까? 예를 들어 호출 스레드에서이를 실행할 수 있지만 특정 시간보다 오래 걸리면 실행을 백그라운드 스레드로 옮길 수 있습니까? ?한 스레드에서 다른 스레드로 실행을 위임 할 수 있습니까?

대리자가 비동기로 작성되었다고 가정합니다. 동기 블록을 사용하여 병렬 처리를 높이기 위해 백그라운드 스레드로 이동하려고하지는 않지만 간단한 작업을 위해 스레드 오버 헤드를 피하여 비동기 실행 성능을 향상 시키려합니다. 나는 등을 명확 스택 경계를 설정할 수 있다면 대리자 또는 람다의 실행을 일시 정지 할 수있는 방법이 있는지

은 기본적으로 내가 궁금하네요, 다른 스레드로 이동하고 다시

난이 가능 의심 , 나는 단지 호기심이 많다.

답변

3

가능한 일이지만 어색하고 어려울 것입니다. 이를 수행하는 가장 좋은 방법은 coroutines을 사용하는 것입니다. 현재 coroutine 패러다임에 맞는 .NET의 유일한 메커니즘은 yield return 키워드를 통해 C#의 반복기입니다. 은 이론적으로 해킹하여 어떤 스레드에서 다른 스레드로 전환하는 메서드 실행을 허용합니다. . 그러나이 블로그는 가치있는 해킹 일 뿐이지 만 가능하다고 생각합니다.

다음으로 가장 좋은 방법은 Async CTP으로 업그레이드하는 것입니다. 이 기능은 C#에서 사용할 수 있으며 사용자가 원하는 것을 정확히 수행 할 수있게 해줍니다. 이것은 제안 된 await 키워드와 함께 포함되는 영리한 공격으로 우아하게 완성됩니다. 최종 결과는 다음과 같습니다.

public async void SomeMethod() 
{ 
    // Do stuff on the calling thread. 

    await ThreadPool.SwitchTo(); // Switch to the ThreadPool. 

    // Do stuff on a ThreadPool thread now! 

    await MyForm.Dispatcher.SwitchTo(); // Switch to the UI thread. 

    // Do stuff on the UI thread now! 
} 

이것은 단지 새 await 키워드로 할 수있는 많은 악인 멋진 트릭 중 하나입니다.대상은 특별히 작업 항목의 형태로 주입을 수용하도록 설계되어있는 경우 실제로 기존 스레드에 코드의 실행을 삽입 할 수


1 수있는 유일한 방법입니다.

2 당신은 반복자와 await 키워드를 모방에서 하나 개의 시도에 대한 내 대답 here을 볼 수 있습니다. MindTouch Dream 프레임 워크는 아마도 더 좋은 대안입니다. 요점은 일부 독창적 인 해킹으로 스레드 전환을 유발할 수 있어야한다는 것입니다.

+0

매혹적인! Await과 Async CTP에 대해 좀 더 연구해야 할 것입니다. 나는 내가 그것에 대해 잠시 후에 읽었을 때''기다리고있는 것 ''이 전부 였다고 나는 확실히 알지 못했다. – devios1

+0

와우; 그거 매끄럽다. –

2

쉽지 않습니다.

대리인을 상태 시스템으로 구성하면 상태 간 실행 시간을 추적 할 수 있고 원하는 임계 값에 도달하면 새 스레드에서 다음 상태를 시작할 수 있습니다.

더 간단한 해결책은 새 스레드에서 시작하는 것입니다. 용납 될 수없는 이유가 있습니까?

는 (내 휴대 전화에서 게시 - 필요하면 내가 진짜 키보드에있을 때 나는 어떤 의사를 제공하지 것이다)

+0

흠, 그건 제가 고려하지 않은 흥미로운 아이디어입니다. 제 목적을 위해, 저는 대리인의 형식을 매우 단순하게 유지하는 것에 더 관심이 있습니다 (상태 머신은 과도하게 사용됩니다). 아마도 스레드 풀 스레드를 사용하는 경로가 끝날 것입니다. 사소한 작업을 위해 최적화 할 수있는 방법이 있다면 궁금했습니다. – devios1

+0

그래, 너는 말하자면, 반복적으로 동일한 작업을하고 있다고해도, FSM은 잔인하다. 이 경우 예상 워크로드/반복을 기반으로 필요한 exec 시간을 예측하고 사용할 스레드에 대한 결정을 내릴 수 있습니다. –

+0

그래, 저도 그것에 대해 생각해 봤습니다 ... 지난 실행 시간의 데이터베이스를 유지하고 평균을 사용하여 백그라운드 스레드에서 실행해야하는지 여부에 대한 정보에 근거한 결정을 내릴 수 있습니다. 물론 모든 메트릭을 수행하는 것이 현재 스레드에서 실행하여 얻을 수있는 최적화보다 오래 걸리는 것을 고려해야합니다 (실제로는 거의 보장됩니다). 그래서 정말로 그것은 논점이됩니다. 그래도 생각하는 것이 흥미 롭습니다. – devios1

1

없음 나는 그것이 가능하다고 생각하지 않습니다. 적어도 정규 대리인과 직접적으로는 관계 없습니다. 약간의 작업 후에 생성 된 일종의 IEnumerable을 만든 경우에는 수동으로 몇 번의 반복을 실행 한 다음 너무 많은 반복 작업 후에 백그라운드 스레드에서 실행하도록 전환 할 수 있습니다.

ThreadPool 및 TPL의 작업은 많이 수행해야하며 항상 백그라운드 스레드에서 실행해야합니다. 작업을 사용하면 오버 헤드가 발생한다는 특정 벤치 마크가 없으면 조기에 최적화하려고하는 것처럼 들릴 수 있습니다.

+0

사실, 조기 최적화에 대해 옳았고 잘 알고 있습니다 (저는 조기 최적화 문제가 있음을 인정합니다). 그렇기 때문에 내가 왜 그렇게 진지하게 받아들이지 않을지, 미래의 잠재적 인 개선을위한 호기심에서 벗어났다. ;) – devios1

관련 문제