문제

방금 소형 Xbox 360 무선 컨트롤러 관리 인터페이스를 작성하여 기본적으로 저 레버 주위를 감싸고 있습니다. Slimdx 래퍼 라이브러리이며 Xbox 360 컨트롤러 용으로 쉽고 관리되는 API를 제공합니다.

내부적으로 클래스는 매번 게임 패드를 설문 조사하고 컨트롤러의 기본 상태의 변화를 감지하면서 이벤트를 촬영합니다.

나는 두 가지 악 중 하나를 선택하도록 강요하는 타이머로 막 다른 골목을 경험하고 있습니다.

  • 내 Xbox360Gamepad 클래스 UI 프레임 워크를 구체적으로 만들 수 있습니다 (즉, 지원 WPF/WinForms는 클래스에서 하드 코딩되며 클래스는 이러한 프레임 워크를 참조해야합니다 ...)

  • 클래스를 완전히 프레임 워크로 만들지 만 사용자는 Dispatcher.invoke / invoke () 호출을 통해 코드를 뿌리도록 강요하여 생성 된 이벤트에 따라 UI를 업데이트 할 수 있습니다.

후자의 옵션을 선택하면 (코드 UI Agnostic을 만드는) 기본적으로 "generic"system.timers.timer 또는 UI 종속성이없는 타이머를 사용합니다. 이 경우 UI, 즉 WPF에서 UI를 직접 업데이트 할 수없는 스레드에서 이벤트를 생성/호출하게됩니다. 즉 .

반면에 Xbox 360 컨트롤러 클래스 내부에서 DispatcherTimer를 사용하면 소란없이 UI를 직접 업데이트 할 수있는 작업 구성 요소가 있지만 이제 전체 컨트롤러 클래스가 WPF에 연결되어 있으며 존재하지 않고 사용할 수 없습니다. WPF에 의존 (예 : 순수한 콘솔 앱에서)

내가보고있는 것은 내가 프레임 워크가 아프지 않은 것이고 모든 종류의 디스패처에 의지하지 않고도 UI를 업데이트 할 수있는 일종의 일종의 솔루션입니다. 모든 타이머에 대한 클래스, 나는 관련 시나리오에 따라 타이머를 종속성으로 주입 할 수 있습니다. 이런 종류의 문제를 성공적으로 다루어 본 적이 있습니까?

도움이 되었습니까?

해결책 3

그래서 ... 정보 / 코드 @가 나타납니다. http://geekswithblogs.net/robp/archive/2008/03/28/why-doesnt-dispatcher-implement-isynchronizeinvoke.aspx 실제로 작업 솔루션을 제공합니다. 이 코드는 모든 UI와 완전히 독립적이며 대신 적절한 UI / 스레드 통합을 위해 isynchronizeinvoke에만 의존합니다.

방금 이것을 사용했지만 여전히 그대로 두는 것을 꺼려합니다.

내 문제의 요점은 모든 이벤트 호출 함수가 다음과 같이 보인다는 것입니다.

protected virtual void OnLeftThumbStickMove(ThumbStickEventArgs e)
{
  if (LeftThumbStickMove == null) return;

  if (_syncObj == null || !_syncObj.InvokeRequired)
    LeftThumbStickMove(this, e);
  else
    _syncObj.BeginInvoke(LeftThumbStickMove, new object[] { this, e });
}

이런 식으로 코드를 작성하는 것은 매우 성가시고 혼란 스럽습니다. 저에게는 저에게 빌어 먹을 물건을 얻는 데 너무 많은 소란이 생겼습니다. 기본적으로 나는 모든 이벤트 호출을 너무 많은 논리로 랩핑하는 것을 좋아하지 않습니다 (!)

따라서 다른 / 추가 전략을 선택했습니다. 기본적으로 Xbox360Gamepad 클래스의 생성자는 다음과 같습니다.

public XBox360GamePad(UserIndex controllerIndex, Func<int, Action, object> timerSetupAction)
{
  CurrentController = new Controller(controllerIndex);
  _timerState = timerSetupAction(10, UpdateState);
}

보시다시피, 타이머를 생성하고 연결하는 기능을 수용합니다.

이는 기본적으로 360 컨트롤러 클래스 내에서 UI 특정 타이머를 사용할 필요가 없음을 의미합니다. 본질적으로 컨트롤러의 "기본값"생성자는 다음과 같습니다.

public XBox360GamePad(UserIndex controllerIndex) : 
  this(controllerIndex, (i,f) => new Timer(delegate { f(); }, null, i, i)) {}

Lambda 함수를 사용하여 타이머 "서비스"에서 컨트롤러 클래스의 종속성을 코딩합니다.

WPF에서 나는보다 일반적인 생성자를 사용하여 컨트롤이 다음과 같이 Dispatchertimer를 사용할 것인지 확인합니다.

  _gamePad = new XBox360GamePad(UserIndex.One, (i, f) => {
    var t = new DispatcherTimer(DispatcherPriority.Render) {Interval = new TimeSpan(0, 0, 0, 0, i) };
    t.Tick += delegate { f(); };
    t.Start();
    return t;
  });

이런 식으로 기본적으로 기본 구현이 WPF 또는 WinForms 특정 코드를 사용할 필요가없는 컨트롤에 타이머 구현을 제공하기 위해 "사용자"에 맡깁니다.

나는 개인적으로 isynchronizeinvoke를 사용하는 것보다 더 유용하고 더 좋은 디자인을 찾습니다.

나는이과 같은 사람들의 피드백을 듣고 싶습니다 / 이것을 개선하고 싶어합니다 / 이것에 의해 혐오감을 느낍니다.

다른 팁

폴링 아키텍처가 유일한 옵션입니까?

어쨌든 개인적으로 나는 시스템을 재구성하여 외부 세계가 컨트롤러 클래스에서 해고 된 이벤트를 구독 할 수 있도록 시스템을 재구성 할 것입니다.

컨트롤러가 올바른 스레드 컨텍스트에서 이벤트를 발사하려면 isynchronizeinvoke 인터페이스에 대한 속성을 추가 하고이 속성이 컨트롤러 내부에 포함되지 않은 경우 인터페이스를 사용하십시오. 그렇지 않으면 이벤트를 직접 호출하십시오. 컨트롤러가 실행되는 스레드.

예를 들어, 전체 폴링을 모든 n 밀리 초를 깨우는 스레드로 만들어 작업을 수행하거나 이벤트 객체를 사용하여 이벤트를 기다리기 만하면됩니다 (360 컨트롤러 아키텍처에 이와 같은 것이있는 경우).

360 컨트롤러는 현재 상태 만보 고 할 수 있습니다. 여론 조사없이 국가를 얻는 다른 방법은 없습니다. system.threading.timer를 사용하거나 Thread.Sleep ()를하는 새 스레드를 열면 내 관점에서 실제로 동일합니다. 둘 다 UI-Less 타이머 클래스의 기능을 충족합니다.

isynchronizeinvoke에 대해 언급 해주셔서 감사합니다. 더 많은 것을 검색하고 내 고통을 공유하고 해결책을 가질 수있는 사람을 찾았습니다.http://geekswithblogs.net/robp/archive/2008/03/28/why-doesnt-dispatcher-implement-isynchronizeinvoke.aspx

나는 그의 코드를 시도 하고이 스레드를 계속 게시 할 것입니다 ... 팁 감사합니다!

또한 Microsoft Robotics Developers Studio의 일부인 동시성 및 조정 런타임을 살펴볼 수 있습니다 (그러나 곧 독립형 제품이 될 것입니다).

CCR은 MRD가 로봇 주위를 운전하는 조이스틱과 같은 것들을 완전히 지원하고 메시지 통과 모델에서 작동 할 수있는 스레드 코디네이터입니다. Xbox 조이스틱의 데이터를 요청하는 타이머를 설정하여 데이터를 포트 (큐)에 게시 할 수 있습니다. 그런 다음 데이터를 조이스틱 포트에 게시하여 작업을 처리 할 때 (수신기) 호출되는 메소드를 설정합니다. Winforms의 어댑터가 제공되며 WPF 용 어댑터를 작성하는 것은 어렵지 않습니다.

다음은 본격적인 MRD없이 CCR을 사용하는 방법을 보여주는 멋진 기사입니다.http://msdn.microsoft.com/en-us/magazine/cc163556.aspx

내 경험상, 일단 당신이 당신의 벨트 아래에서 CCR의 기본 사항을 얻으면, 멀티 스레드 동시 비동기 프로그래밍을 수행하는 것은 실제로 쉬워집니다.

@MattValerio : CCR에 대해 알고 있지만 GoogleCode에 컨트롤을 넣을 계획이므로 CCR은 프레임 워크 나 OpenSource의 일부가 아니기 때문에 여기에 청구서에 적합하지 않습니다.

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