문제

콘솔 또는 GUI의 두 가지 모드가있는 winforms 앱을 작성하고 있습니다. 동일한 솔루션 내의 세 가지 프로젝트, 콘솔 앱 용은 UI 양식 용 및 세 번째는 두 인터페이스가 모두 연결될 논리를 보유합니다. 콘솔 앱은 절대적으로 매끄럽게 작동합니다.

사용자 선택을 보유하는 모델은 IList<T> 여기서 t는 로컬 대상입니다. Step, 그것을 구현합니다 INotifyPropertyChanged, UI에서 이것은 DatagridView에 장착됩니다. 모두 런타임에 적합하며 객체의 초기 상태는 화면에 반영됩니다.

각각 Step 객체는 차례로 수행되는 작업입니다. 속성 중 일부는 변경되어 Ilist에 다시 반영되어 DatagridView로 전달됩니다.

UI 버전 의이 작업은 UI로 되돌아가는 이벤트를 제작하여 배경 작업자를 만들어 수행합니다. 그만큼 Step 그것을하고 생성합니다 StepResult 결과를 나타내는 열거 형 유형 (예 : 실행, notrun, ok, notok, caveat)과 메시지를 표시하는 문자열 (단계가 실행되었지만 예상대로는 기언이 없기 때문에)을 나타냅니다. 일반적으로 작업에는 데이터베이스 상호 작용이 포함되지만 디버그 모드에서는 결과를 무작위로 생성합니다.

메시지가 null이면 문제가 없지만 다음과 같은 응답을 생성하면 다음과 같습니다.

StepResult returnvalue = new StepResult(stat, "completed with caveat")

DataGridView가 생성 된 스레드 이외의 스레드에서 액세스하고 있다는 오류가 발생합니다. (필요할 때 호출을 처리 해야하는 사용자 정의 핸들러를 통해 이것을 전달합니다.

그런 다음 고유 한 응답을 생성하면 예를 들어 임의 숫자를 사용합니다. r:

StepResult returnvalue = new StepResult(stat, r.ToString());

동작은 문제없이 성공하며 숫자는 DataGridView에 깨끗하게 기록됩니다.

나는 당황했다. 나는 그것이 어떻게 든 문자열 문자 문제라고 가정하지만 누구든지 명확한 설명을 생각해 낼 수 있습니까?

도움이 되었습니까?

해결책

이벤트 구독을 통해 UI 바인딩을하고 있기 때문에 도움이 될 수 있습니다; 서브 클래스의 방법을 보여주는 예를 들어 쓴 예입니다. BindingList<T> 알림이 UI 스레드에 자동으로 마샬링되도록합니다.

Sync-Context (예 : 콘솔 모드)가 없으면 간단한 직접 호출로 되돌아 가므로 오버 헤드가 없습니다. UI 스레드에서 실행할 때는 이것이 본질적으로 사용합니다. Control.Invoke, UI 스레드에있는 경우 자체가 직접 대의원을 실행합니다. 따라서 데이터가 아닌 스레드에서 데이터를 편집하는 경우 스위치 만 있습니다.

다른 팁

당신은 당신 자신의 질문에 대답했습니다 :-

DataGridView가 생성 된 스레드 이외의 스레드에서 액세스하고 있다는 오류가 발생합니다.

Winforms는 양식과 컨트롤에서 수행 된 모든 작업이 형태가 생성 된 스레드의 맥락에서 수행된다고 주장합니다. 이에 대한 이유는 복잡하지만 기본 Win32 API와 관련이 있습니다. 자세한 내용은 다양한 항목을 참조하십시오 오래된 새로운 것 블로그.

당신이해야 할 일은 invokerequired 및 호출 방법을 사용하여 동일한 스레드 (pseudocodeish)에서 컨트롤에 항상 액세스 할 수 있도록하는 것입니다.

object Form.SomeFunction (args)
{
  if (InvokeRequired)
  {
    return Invoke (new delegate (Form.Somefunction), args);
  }
  else
  {
    return result_of_some_action;
  }
}

나는 전에이 같은 문제가 있었다. 어쩌면 내가 그것에 대해 게시 한이 기사가 도움이 될 수 있습니다.

http://cyberkruz.vox.com/library/post/net-problem-async-and-windows-forms.html

이 기사를 찾았습니다 - "다른 스레드에서 iBindingList를 업데이트합니다" - 바인딩리스트에 비난의 손가락을 가리 켰습니다.

Bindinglist는 비동기 작업을 위해 설정되지 않으므로 제어 된 스레드와 동일한 스레드에서 BindingList를 업데이트해야합니다.

부모 양식을 명시 적으로 전달합니다 ISynchronizeInvoke 객체와 래퍼 만들기 BindingList<T> 트릭을했다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top