2013-02-07 1 views
4

PCI 버스를 통해 내 PC에 연결된 하드웨어가 있습니다. 장치 드라이버 주변의 .NET 래퍼를 통해 하드웨어에 액세스하고 있습니다.PCI 버스에 연결된 장치에 비동기 적으로 액세스하려면 스레드를 사용해야합니까?

장치가 PCI 방식으로 수행되는 방법에 대한 사양이 없습니다. 어느 것이 저의 첫 번째 질문으로 연결됩니다.

1) PCI를 통해 연결된 장치가 특정 속도로 데이터를 전송하도록 보장되어 있습니까?

2) 기기와 통신 할 때 내 UI가 응답 속도를 유지하고 싶습니다. 스레드 풀에서 장치와의 통신을 시작하는 것이 좋습니까? 아니면 PCI 버스에 얼마나 빨리 액세스하는지 비교하는 오버 헤드가 너무 큽니까?

편집 :
질문이 다시 작성되었습니다. 긴 노동 일의 끝을 지나치게 반영했다.
스레드가 스레드 풀 스레드가되도록 요구 사항이 제거되었습니다.

+0

PCI 버스 리소스에 액세스하려면 권한이 부여 된 I/O 명령어를 실행하고 포인터를 물리적 버스 주소에 매핑 할 수있는 유일한 종류의 코드 인 장치 드라이버가 필요합니다. C#에서는 이러한 코드를 작성할 수 없습니다. –

+0

드라이버를 제외시키려는 추상화 수준 및 드라이버의 .NET 래퍼입니다. 근본적인 질문은 동일하게 남아 있습니다. – kasperhj

+1

기술적으로는 작동하지만 스레드를 독점적으로 사용할 수는 없습니다. 그것은 풀입니다. 아이디어는 특정 작업에 이러한 스레드를 사용하고 릴리스하는 것이 좋습니다. 당신은 당신 자신의 쓰레드를 만들 수 있고 (그것의 우선 순위 등을 제어한다.), 쓰레드 풀을 사용하지 않는다. –

답변

3

가 데이터를 제공하기 위해 보장 PCI를 통해 연결 장치 위치 : 내가 여기에 도움이 될 확실하지 오전하지만 난 보통 (종종 WinUSB 장치의 나를 위해) 하드웨어 상호 작용을 다루는 방법을 설명하는 조각이다 특정 속도? ? 내 이해하는

번호, PCIbus mastering와 공유 버스, 일시적으로 전체 버스 대역폭을 활용하는 하나의 장치를 할 수있는 기능입니다. non-server environments에서는 보통 133MB/s의 대역폭을 의미합니다. PCI 버스에 몇 개의 I/O 카드가 있으면 부하가있을 때 대역폭이 부족해질 수 있습니다. 장치를 잘못 사용해도 대기 시간에 부정적인 영향을 줄 수 있습니다. 일부 컨트롤러는 드라이브가 I/O에 응답 할 때까지 멈추지 만 허용 된 경우 비정상적인 상황입니다.

기기와 통신 할 때 내 UI가 의 응답을 유지하도록하고 싶습니다. 스레드 풀에서 장치와의 통신을 시작하는 것이 좋습니까? 아니면 과 관련된 오버 헤드가 PCI 버스에 얼마나 빨리 액세스하는지 비교하면 너무 큽니까?

사용자 지향 소프트웨어를 작성할 때 UI를 I/O 또는 다른 장기 실행 프로세스와 분리하는 것이 좋습니다. 예를 들어, 현대 Android SDK는 HTTP 클라이언트에서이를 강제합니다. UI 스레드에서 HTTP 요청을 실행하면 예외가 발생합니다.

대상으로하는 .NET 프레임 워크의 버전에 따라 장치 통신을 UI에서 분리 할 수있는 몇 가지 옵션이 있습니다. 다양한 옵션의 개요를 보려면 Parallel Processing and Concurrency in the .NET Framework을보십시오. 스레딩은 저수준 추상화이며,보다 쉽게 ​​오류가 발생하기 쉽고 Tasks 또는 C#의 async and await keywords과 같은 더 높은 수준의 추상화를 사용할 수 있습니다.

4

일반적으로 스레드 선호도없이 코드를 작성할 수있는 경우 언제든지 그렇게하는 것이 좋습니다. 그렇게하면 응답 스레드 문제가 발생할 때 UI 스레드를 끌 수있는 자유가 있습니다. Async 메서드를 사용하여이 I/O 용 API를 디자인하면 옵션을 계속해서 좋은쪽으로 열어 둘 수 있습니다.

오랫동안 스레드 풀을 차지할 필요가 없다면 현재 사용중인 스레드가 스레드 풀 스레드인지 또는 사용자가 스폰하는 스레드인지 여부가 중요하지 않습니다. 비동기 I/O를 수행 할 수 있다면 스레드 풀 스레드가 정상적으로 작동해야합니다.

2

하드웨어 상태를 모니터링해야 할 때 장기 실행 백그라운드 스레드를 사용하는 것이 좋습니다. TaskCreationOptions.LongRunning은 좋은 착용감입니다.

또한 비동기 적으로 장치와 상호 작용하기 위해 C#의 새로운 async/await 기능을 사용하면 나에게 의미가 있습니다.

class Controller : IDisposable // to dispose the unmanaged resources related to the hardware 
{ 
    // this will be used to call back to the UI 
    private static readonly SynchronizationContext DefaultContext = new SynchronizationContext(); 

    public Controller() 
    {   
     Task.Factory.StartNew(this.Monitor, ct, TaskCreationOptions.LongRunning); 
    } 

    public async Task<Result> ActionOnHardwareAsync(object parameter) 
    { 
     // you may need to synchronize with the monitor method here. 
    } 

    // This method monitors hw status, calling back to the UI when something happens 
    private void Monitor(object state) 
    { 
     // Do some stuffs... 
     this.synchronizationContext.Post(~ your SendOrPostCallback here ~, ~ event from the hw ~); 
    } 
} 
관련 문제