2012-10-18 4 views
3

서버 측에서 계산중인 일부 소프트웨어로 작업하고 있습니다. BackgroundWorker를 사용해 보았는데 fat 클라이언트에서 웹 서비스로 전환 할 때까지 완벽하게 작동했습니다. 오류 (내 동료가 내게 말한 것으로 인해 이미 예상 했음) "BackgroundWorker가 Serializable로 표시되지 않았습니다"가 발생했습니다. 내 응용 프로그램의 목표는 계산 진행과 현재 계산중인 레코드의 이름으로 클라이언트를 업데이트하는 것입니다. 필요한 경우 일부 코드를 게시 할 수 있지만이 경우 문제와 관련이 있는지 의심 스럽습니다. 내가 달성하기 위해 노력하고있는 무슨의 방식은 다음과 같이 표시 될 수있다 :BackgroundWorker보다 비동기 적으로 상태를 업데이트하는 다른 방법

  • 클라이언트는 버튼을
  • 클라이언트가 기록 목록을 수신
  • 서버는
  • 서버가 데이터를 전송하는 전화를 가져옵니다 "준비"히트 확인
  • 클라이언트가 선택한 것을 확인한 다음 (배경 작업자를 설정하여 서버에 보냄)
  • 서버가 전화를받습니다. 백그라운드 작업자의 참조와 계산에 필요한 모든 레코드를받습니다.

    worker.ReportProgress(i * 100/ids.Length, "Currently counting: " + id + "..."); 
    Calculate(ids[i]); 
    worker.ReportProgress((i+1) * 100/ids.Length, "Currently counting: " + id + "..."); 
    

어떤 방법이 : 한 번)

  • 나는 레코드를 운영하는 루프 (각 계산은, 다음과 같은 경우 BackgroundWorker의 상태를 업데이트) ~ 1-3초 소요 내가 웹 서비스에서도 역시 일하려고하는 것을 이루기 위해서? BackgroundWorker를 Serializable으로 속이거나 서버에서 클라이언트로 상태를 업데이트하는 다른 방법이 있다고 가정합니다.

    P. 나는 서버에서 많은 양의 데이터를 보내지 않고 있습니다. (실제로는 id와 같은 데이터도 더 보내려고 시도 할 수도 있습니다.) 그래서 과부하의 문제는 아닌 것으로 가정합니다.

  • 답변

    4

    기본적으로 웹용 코드를 작성하는 경우 지속적인 상호 작용보다는 요청/응답을 기반으로 완전히 다른 모델을 다루게됩니다.

    아마도 초기 요청에서 일종의 "작업 ID"(고유 ID 일 수 있음)를 반환하고이를 신속하게 반환해야합니다. 한편, 백그라운드에서 작업을 시작합니다. 클라이언트는 특정 작업의 상태를 폴링 할 수 있습니다. 상태가 변경 될 때까지 각 요청이 중단되거나 클라이언트가 서버를 정기적으로 호출하도록 "긴 폴링"을 사용할 수 있습니다. 어느 쪽이든 응답은 진행률 (처리되는 레코드의 수와 현재 레코드의 이름)이됩니다.

    +0

    답장을 보내 주셔서 감사합니다. 나는 * 클라이언트가 서버를 정기적으로 호출하도록했다. *하지만 상태에 변화가있을 때까지 각 요청이 어떻게 처리 될지를 묻고 싶다. 필자는 값 변경을 지속적으로 확인하는 루프를 사용하여이 작업을 성공적으로 수행 한 다음 함수가 새 값을 반환 할 수있게했습니다. 그러나 그것은 무서운 보이지 않는 아무것도하지 않고 수백만 번 반복합니다. (짧은 질문으로 : while (! green_light) {/ * 멈춤 라인에서 기다림 = 아무 것도하지 말라 * /} drive();' 수백만 회 반복 할 필요없이 가장 쉬운 방법으로 반복 할 수 있습니까? –

    +0

    그렇습니다. Thread.Sleep()을 사용할 수는 있지만 귀중한 시간을 낭비하고 싶지는 않습니다. 예를 들어 1.05 초 후에 값이 변경되면 0, 1, 2s에서 검사하여 0.95s를 낭비하지 마십시오. –

    +0

    @ AndriusNaruševičius : 긴 폴링을 구현하는 것이 더 까다로울 것입니다. 최소한 AJAX/브라우저에 도움이되는 다양한 프레임 워크가 있습니다. 상호 작용 (예 : SignalR) - 웹 서비스에서 얼마나 잘 작동하는지 모르겠다. (특히 .NET 4.5의 경우) 비동기 웹 서비스 지원을 더 잘보아야 할 수도있다. 분명히 단단한 루프가 아닌 수면을 원한다. * 진짜 * ap인가? 사용자가 진행 상황을보기 위해 여분의 초를 기다려야한다면 문제가되는 것일까 요? –

    0

    백그라운드 작업자 멤버 변수가있는 클래스의 인스턴스를 serialize하려고하는 것이 걱정됩니다. 배경 작업자가 직렬화 가능 객체가 아니기 때문에 그렇게 할 수 없습니다.

    당신이 여기에서 할 수있는 것은 -

    • 는 비동기 적으로 실행하는 방법을 가지고있는 클래스를 만듭니다.
    • 배경 작업자의 진행 상황을 저장하는 클래스에 멤버 변수를 만듭니다.
    • 진행률 값을 반환하는 클래스에서 웹 메서드를 만듭니다.

      • 가 비동기 적으로 실행해야하는 메소드를 호출에

    • 지금 페이지에 당신이 필요합니다.
    • 일정한 간격으로 실행되는 클라이언트 측 javascript를 넣습니다. 웹 서비스를 쿼리하고 진행 상황을 묻습니다.
      • 페이지를 업데이트하고 진행률을 표시하십시오.

    는 내가 제대로 설명했습니다 바랍니다.

    0

    서비스를 통해 수시로 프로세스를 업데이트하고 싶으면 (비표준 완료시) 비동기 서비스를 사용하도록 제안하십시오. WCF를 사용하고 비동기식 서비스를 작성하십시오 (예 : http://blogs.msdn.com/b/rjacobs/archive/2011/06/30/how-to-implement-a-wcf-asynchronous-service-operation-with-task-lt-t-gt.aspx과 같은 주제를보십시오).

    public int onBlockComplete(IAsyncResult result) 
    { 
        //... 
    } 
    

    같은 몇 가지 방법을 생성하고 클라이언트에서이 문제를 처리합니다. 또한 전체 프로세스가 완료 될 때 콜백 메소드를 구현하십시오.

    이렇게하면 블록 완료 이벤트를 처리하고 클라이언트에서 진행 상황을 표시 할 수 있습니다.

    물론 ASP.NET에서 클라이언트를 구현하는 경우 페이지를 새로 고쳐 업데이트를 확인해야합니다.

    관련 문제