2013-02-03 2 views
0

문제점에 대한 효율적인 해결책을 찾고 있습니다. VS 2010을 사용하고 있습니다. wcf 서비스 메소드에서 일련의 작업을 수행하고 각 작업 상태를 호출 클라이언트로 되돌리고 싶습니다. 콜백 계약을 사용하여 wcf를 설정하고 이중 채널을 사용하여 wcf에 연결할 수 있습니다. 장기 실행 작업을 시작할 때 가끔씩 다시 호출을 트리거합니다. 나는 이유를 모른다. 아래는 제가 따라 갔던 방법입니다. WCF 서비스 방법에서 C# Backgroundworker New Issue

여기서

public void Start() 
    { 
     List<Employee> empLists = GetEmpData(); // geting lots of employee objects 
     foreach(Employee emp in empLists)  // maybe 1000 records 
     { 
      StartlongRunning(emp); 
     } 
    } 

private void StartlongRunning(Employee emp) 
{ 
    // here i am creating a new background worker... 
    // Here i am registering for RunWorkerCompleted, DoWork, ReportProgress events... 
    bgw.RunWorkerAsync(emp) 
} 

void bgw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    Employee emp = (Employee)e.Argument; 
    using (ClassA p = new ClassA(emp.ID)) // this class is from another dll. 
    { 
     e.Result = p.StartProcess(emp.Code); 
    } 
} 

void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    // This is not calling properly. 
    // Sometimes this method is working...most of the time it is not working.. 
    // here i am unregistering the registerd DoWork, RunWorkerCompleted events... 
    // calling bgw.Dispose(); // i tried without this also;...but no use... 
    // from here I am firing the callback to client... 
} 

는 StartProcess 방식의 구현이다.

public string StartProcess(string empcode) 
{ 
    // call to another method1() // here saving to DB frequently. works fine 
    // call to another method2() // here also saving to DB frequently. works fine 
    // call to someother method3() // here also some DB insert frequently. fine 
    // call to Method4() // here also some DB insert. 
          // this method is not calling frequently.. 
          // sometimes it is calling but most of times not..why ??? 
    return value; 
} 

private void SaveToDB(args1, args2...) 
{ 
    DatabaseHelper.Save(args1, args2.....); // this static class is from another dll 
    // only DB operation in this static class.. 
} 

이 정적 클래스의 구현은 다음과 같습니다.

using (SqlConnection conn = new SqlConnection(DBConnection)) 
{ 
    conn.open; 
     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
     ...adding parameters 
     cmd.ExecuteNonQuery(); 
     } 
     conn.close(); 
} 

StartProcess 반환 경우, 백그라운드 작업자는 RunWorker 방법을 실행합니다. 그러나 그것은 일어나지 않습니다. 여기서 무엇이 잘못 되었습니까?

각 배경 작업자마다 ClassA 개체를 각각 생성합니다. 그리고 일단 객체가 완료되면 ClassA이 처리됩니다.

그러나 StartProcess이 호출을 올바르게 반환하지 않는 이유를 알 수 없습니다.

내 구현에는 백그라운드 작업자간에 ClassA 개체가 겹치는 부분이 있습니까 ??

+0

이것이 문제가 될지 모르지만 1000 개의 SqlConnections를 동시에 열려고하는 것 같습니다. 한 번에 얻을 수있는 연결 수는 데이터베이스 서버 구성 문제입니다. DB가 세 개의 연결 만 제공하는 경우 세 가지 연결에 대한 작업이 사용될 때까지 대기 상태의 거의 모든 백그라운드 스레드로 끝납니다. –

+0

@PhillipScottGivens. 답장을 보내 주셔서 감사합니다. 그러나 때로는 제대로 작동합니다. 응용 프로그램을 실행할 때 각 테이블의 개수를 실행하여 DB를 검사했습니다. SQL 쿼리 창에서 run buton을 자주 클릭 할 때마다 메서드 1, 2 및 3의 테이블에 대한 수가 증가합니다. 그러나 방법 4의 테이블은 업데이트되지 않습니다. 하지만 1 또는 2 번 내가 그쪽으로 애플 리케이션을 실행하면, 모든 4 테이블은 모든 것을 제대로 작동하고 있다는 의미를 보여주는 것입니다. 나는 undestand를 여기에서 문제가 무엇이겠습니까 ?? –

답변

1

나는 그것이 바쁘지 않은지 확인하지 않고 루프에서 RunWorkerAsync를 호출하는 것이 문제라고 생각합니다. 다른 스레드에서 모든 작업을 시작하지 않고 목록으로 RunWorkerAsync를 매개 변수로 호출해야합니다.

public void Start() 
{ 
    List<Employee> empLists = GetEmpData(); // geting lots of employee objects 
    StartlongRunning(empLists); 
} 

을 따라 bgw_DoWork을 변경

나는 같은 것을 할 것입니다.

진행 상황을 확인하려면 각 직원 개체에 대해 ReportProgress를 호출 할 수 있습니다.

+0

나는 이것이 좋은 생각이라고 생각하고 그것을 체크하게한다. 그러나 순차적 실행은 성능에 영향을 미칩니 까 ??? –

+0

네, 잘 작동합니다.그러나 각 항목을 실행하는 데는 많은 시간이 필요합니다. 나는 그것을 평행하게하는 것을 찾고있었습니다. –

+0

나는 데이터베이스를 업데이트하는 중이라고 생각했는데, 데이터베이스를 병렬로 만들면 데이터베이스가 업데이트되는 동안 테이블과 인덱스를 잠그므로 데이터베이스가 순차적으로 만들어지기 때문에 데이터베이스를 훨씬 빠르게 만들지는 못한다. – Casperah

0

동시에 여러 backgroundWorkers와 작업 할 응용 프로그램을 만들려면 수행중인 작업마다 새 backgroundWorker 객체를 초기화해야합니다. 문제가 해결됩니다.

+0

바실리카. 답장을 보내 주셔서 감사합니다. 하지만 각 작업에 대한 새로운 bgw를 만들고 있습니다. 아이디어를 더 많이 지정할 수 있습니까? –

+0

알다시피. 동일한 backgroundWorker를 실행 중입니다. BackgroundWorker를 만들 수 있습니다. bw = new BackgroundWorker(); 인스턴스 또는 배열을 호출 할 수 있습니다. 디자이너가 아닌 코드에서 이벤트를 각각에 대해 추가 할 수 있습니다. worker.DoWork + = 새 DoWorkEventHandler (update.DoUpdate); –