2009-11-26 3 views
0

VB6로 작성된 EXE 용 C# DLL 플러그인을 만들고 있습니다. EXE 소스에 액세스 할 수 없습니다. DLL 자체가 작동하고 EXE와 통신합니다. 때로는 시간이 오래 걸립니다 C# COM interop을 사용하여 SQL 쿼리 중에 응답하는 UI에 가장 적합한 방법

  • DLL이 데이터를 처리하는 매개 변수로 객체를 전달,

    1. 사용자 문제 EXE에 명령을 다음 DLL에있는 함수를 호출 : 여기

      은 이벤트의 과정이다
    2. DLL은 전달 된 개체의 함수를 호출하여 응답합니다. DLL 함수 자체는 아무 것도 반환하지 않습니다

      public void DoCommand(object CommandSettings) 
      { 
          //ObjectVB6 is my custom class to allow easy calling of COM methods and properties 
          ObjectVB6 CS = new ObjectVB6(CommandSettings); 
          ... //process data 
          CS.CallMethod("MyReply", args); 
      } 
      

    내 문제가합니다 (DLL)에서 긴 쿼리 중에 EXE의 UI가 얼어 것입니다.

    이것을 방지하는 가장 좋은 방법은 무엇입니까? 비동기 MySQL 쿼리를 사용해 보았습니다.이 쿼리는 좋지 않았으며 보호 된 메모리 문제가있는 여러 스레드를 사용하여 시도했습니다.

    제공 할 수있는 조언은 정말 좋습니다. 며칠 동안이 문제를 해결하려고 노력했습니다. 감사.

  • +0

    새 스레드에 권한이 없기 때문에 새 스레드가 EXE에서 전달 된 개체에 액세스 할 수 없으므로 다음 오류가 발생합니다. "보호 된 메모리를 읽거나 쓰려고 시도합니다. 이것은 종종 다른 메모리가 손상되었음을 나타냅니다 . " – Lynxy

    답변

    0

    나는 내가 한 것을 성취 할 방법을 찾았습니다. 더 좋은 방법을 선호하지만,이 방법이 효과적입니다.

    두 개의 대기열을 사용하여 정보를 공유합니다. 메인 쓰레드는 _get 대기열을 수신 대기하고 요청이있을 때 _set 대기열을 설정합니다. 작업자 스레드는 요청을 _get 큐에 삽입하고 _set이 준비 될 때까지 기다립니다. 주 스레드는 단지 프록시처럼 행동합니다.

    도움 주셔서 감사합니다.

    +0

    BackgroundWorker를 사용해 보셨습니까? 당신이 한 것은 BackgroundWorker의 재 구현과 같습니다. AngryHacker의 답변을 시도해보십시오. http://stackoverflow.com/questions/1805514/c-best-approach-for-a-responsive-ui-during-sql-query-using-com-interop/1806825#1806825 – MarkJ

    0

    왜 코드에 작업자 스레드를 사용할 수 없습니까? "보호 된 메모리 문제"란 무엇입니까?

    0

    IMO 가장 좋은 방법은 DLL 측의 ThreadPool에 "불 및 잊기"스타일을 요청하는 것입니다. 이거 해봤 니?

    그렇지 않으면 VB6의 단일 스레드 아파트 모델로 인해 이미 알고있는 것처럼 상황을 파악하기 위해 VB6 프로그램에 콜백 함수를 추가해야합니다.

    VB6에서 멀티 스레딩의 위험과 위험을 더 자세히 살펴 보려면 다음 문서를 살펴보십시오. 그것은 당신이 단순히 스레드를 시작 할 수 있으며이 VB6 측에서 할 수

    VB5에서 멀티 스레딩 및 VB6 .NET에서 개발 된 모든 기능은을 사용하여 비동기 적으로 호출 할 수
    http://www.freevbcode.com/ShowCode.Asp?ID=1287

    +0

    당신이 VB6에서 그것을 해결하고 싶다면, 대신 DLL을 감싸기 위해 ActiveX exe 파일을 만들려고합니다. Microsoft 커피 샘플과 유사 http://msdn.microsoft.com/en-us/library/aa445814(VS.60).aspx – MarkJ

    0

    위임 한 다음 BeginInvoke를 호출하여 함수를 실제로 호출합니다. 함수가 아무 것도 반환하지 않기 때문에 EndInvoke를 호출 할 필요가 없습니다. IAsyncResult를 사용하면 콜백 요구 사항을 충족 할 수 있습니다. 이것을 올바르게 수행하는 방법에 대한 좋은 참고 자료는 O'Reilly가 발행 한 Juval Lowy의 "Programming .NET Components"입니다. ISBN은 0596102070입니다. 행운을 빌어 요.

    1

    는 다음과 같은 시도 : 응답자 중 하나가 말했듯이

    BackgroundWorker bw = null; 
    ObjectVB6 CS = null; 
    
    public void DoCommand(object CommandSettings) 
    { 
        //ObjectVB6 is my custom class to allow easy calling of COM methods and properties 
        CS = new ObjectVB6(CommandSettings); 
    
        // hook up background worker 
        bw = new BackgroundWorker(); 
        bw.DoWork += new DoWorkEventHandler(bw_DoWork); 
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
    } 
    
    private void bw_DoWork(...) 
    { 
        // process data, e.g. the piece that takes too long 
    } 
    
    private void bw_RunWorkerCompleted 
    { 
        CS.CallMethod("MyReply", args); 
    } 
    

    , 이것은 나 때문에 VB6 아파트 스레딩의 특성으로 작동하지 않을 수 있습니다.

    +0

    +1 생각합니다. 작동해야합니다. BackgroundWorker의 요점은 RunWorkerCompleted 이벤트가 원래 스레드에서 발생하므로 VB6 아파트 스레딩에 문제가 없어야한다는 것입니다. – MarkJ

    +0

    @ MarkJ 나는이 접근 방식을 성공적으로 사용했습니다. 대부분의 상황에서는 작동하지만 다른 상황에서는 작동하지 않습니다. 예를 들어, Asterisk.NET을 VB6 프로젝트에 통합하려고 시도했지만 2 주간의 두통과 파란 충돌이있었습니다. – AngryHacker

    관련 문제