2013-02-10 4 views
0

동기 호출에 대해 SL WCF 지원을 위조하는 방법에 대한 아이디어가 떠 올랐습니다. 기본적으로 Silverlight WCF의 비동기 콜백 스레드 잠금

private _completed; 
private IList<Customer> _customers; 
public void IList<Customer> GetAllCustomers() 
{ 
    bool completed = false; 
    DataServiceQuery<Customer> myQuery = this.Context.Customers; 
    myQuery.BeginExecute(OnQueryExecuted, myQuery); 

    while (!_completed) 
     System.Threading.Thread.Sleep(67); //tried join also 

    return _customers; 
} 

private void OnQueryExecuted(IAsyncResult result) 
{ 
    var query = result.AsyncState as DataServiceQuery<Customer>; 
    _customers = query.EndExecute(result).ToList(); 
    _isCompleted = true; 
} 

무슨 일이 영원히 루프이다.

while 루프에 중단 점을 넣고 밖으로 이동하고 실행을 다시 시작합니다. 결과는 매우 밀리 초 후에 나타납니다.

그래서, 결과를받을 수있는 쿼리에 대한 콜백을 생각하고는

SL이 동작을 유지하기 위해 매우 결정 보인다. 쿼리에서 호출 된 동일한 스레드에 대기, 그래서 myQuery.BeginExecute 포장해도됩니다 새 스레드에서는 여전히 동일한 동작을 얻습니다.

/* 편집 : 사실, 그것에 대해 생각하면 대기중인 UI 스레드에 콜백을 대기시킵니다. 이것은 우리가 결과를 얻을 때 Dispatcher.Invoke 할 필요가없는 이유이기도합니다. 여하튼, 전 항상 전용 스레드에서 전체 작업 (기다림이 필요함)을 수행 한 다음 기다릴 수는 있지만,이 작업을 시도하는 시점을 피하면서 리팩토링이 필요합니다. */

이 방법이 있습니까?

+0

'Execute'를 호출하지 않고 왜 UI 스레드를 차단하고 있습니까? 이 메소드'GetAllCustomers'는 여러분이 가지고있는 형태로 결코 비동기 적이되지 않으므로 대신'Execute'를 호출하십시오. 왜 하나의 스레드를 차단하는 대신 두 번째 스레드에 참여하려고하는지 전혀 알지 못합니다. 이점은 전혀 없으며 응용 프로그램 성능이 저하됩니다. 좀 더 자세히 설명해 주시겠습니까? – user1416420

+0

포인트는 비동기가 아닙니다. db 호출은'myQuery.BeginExecute' 때문에 async입니다. 어쨌든, 내가'Execute '를 호출하면 Silverlight는 동기식 쿼리를 지원하지 않는다는 사실을 갑자기 알려줍니다. –

+0

오, 알았어, 나는 몰랐어. 주변을 둘러 볼까 .. – user1416420

답변

1

이 때문에 응답하지 않는 이유는 EndExecute 메서드가 UI 스레드에 marshals하지만 Sleep 호출로 UI 스레드를 차단하고 있기 때문입니다. 스레드를 차단하는 데 어떤 기술을 사용하는지는 중요하지 않습니다. UI 스레드에서 메서드가 호출되면 교착 상태가 발생합니다.

SIlverlight 환경에서 개발할 때 동기 메서드를 사용하는 대신 비동기 적으로 프로그램 할 수 있어야합니다. C# 5.0을 사용하는 경우 async/await 기능을 사용하면 이 비동기 코드로 나타납니다. 동기식이지만 콜백/연속을 사용하는 비동기 호출로 컴파일됩니다. 아직 해당 버전으로 업그레이드하지 않았습니다.

+0

그래서 Win 앱에서 UI 스레드를 차단할 수 있다면 왜 SL에 없습니까? 결국, 당신은 테스트 할 것이고, 무엇인가가 멈 추면 당신은 그것을 비동기 적으로 할 것입니다. 이러한 것들은 어쨌든 100 밀리 초 이내에 다시 들어옵니다. 모든 것을 연속으로 두는 것만이 아니라 여러 가지 동시성 검사를해야합니다. 사용자가 일부 데이터 목록 새로 고침을 클릭하면 되돌아 올 때까지 요소로드를 비활성화해야합니다. 'async/await'는 좋지만이 문제는 해결되지 않습니다. –

+0

그리고 나는 무엇을 얻습니까? 제로! 나는 또한 133ms라고 말하기 위해 기다릴 시간을 제한하고, 서버를 응답하지 않으며 사용자에게 오류를 표시 할 수 있습니다. 작은 왕복에 대해서. 제정신이 아닌 큰 사람은 비동기입니다. 하지만 이제는 지나간 시간을 지나치게 버려야합니다. 이제는 언제 어디서나 비동기로 모든 db 여행을 해봅시다. –

+0

@ h.alex 요점은 UI 스레드를 차단하면 전체 애플리케이션이 정지된다는 것입니다. 페인트 이벤트가 실행되지 않도록하고, 사용자가 브라우저를 이동하지 못하도록하거나, 탐색을 방해하거나 탭을 전환하지 못하도록합니다. 사용자 경험에 지대한 영향을줍니다. – Servy