4

PCI バス経由で PC に接続されているハードウェアがあります。デバイス ドライバーの .NET ラッパーを介してハードウェアにアクセスしています。

デバイスが PCI に関してどのように動作するかについての仕様はありません。それが私の最初の質問につながります。

1) PCI 経由で接続されたデバイスは、特定の速度でデータを配信することが保証されていますか?

2) デバイスと通信するとき、UI の応答性を維持したいと考えています。(スレッドプール) スレッドでデバイスとの通信を開始するのは良い考えですか、それとも PCI バスへのアクセス速度に比べて、これに関連するオーバーヘッドが大きすぎますか?

編集:
質問が書き直されました。長い仕事の一日の終わりを反映しすぎました。
スレッドがスレッド プール スレッドであるという要件が削除されました。

4

3 に答える 3

4

一般に、スレッド アフィニティを使用せずにコードを記述する機会がある場合はいつでも、そうするのが得策であることがよくあります。そうすれば、応答性の問題が発生した場合に、UI スレッドを自由にオフにすることができます。Async メソッドを使用してこの I/O 用の API を設計することで、今後も良い方法でオプションを開いたままにすることができます。

使用しているスレッドがスレッドプール スレッドであるか、自分で生成したスレッドであるかは、長期間占有する必要がない場合には関係ないように思われます。また、非同期 I/O を実行できる場合は、スレッドプール スレッドで問題ありません。

于 2013-02-10T21:22:01.100 に答える
3

PCI 経由で接続されたデバイスは、特定の速度でデータを配信することが保証されていますか?

いいえ。私の理解では、PCIはバス マスタリング機能を備えた共有バスであり、単一のデバイスがバス帯域幅全体を一時的に利用できるようにする機能です。非サーバー環境では、これは通常 133MB/秒の帯域幅を意味します。PCI バスに数枚の I/O カードを接続すると、負荷がかかると帯域幅が不足することがわかります。デバイスの誤動作も遅延に悪影響を与える可能性があります。ドライブが I/O に応答するまでハングするコントローラもありますが、これは異常な状況です。

デバイスと通信するとき、UI の応答性を維持したいと考えています。(スレッドプール) スレッドでデバイスとの通信を開始するのは良い考えですか、それとも PCI バスへのアクセス速度に比べて、これに関連するオーバーヘッドが大きすぎますか?

ユーザー向けのソフトウェアを作成するときは、UI を I/O やその他の長時間実行される可能性のあるプロセスから分離することを常にお勧めします。たとえば、最新の Android SDK は、HTTP クライアントでこれを強制します。HTTP 要求が UI スレッドで実行されると、例外がスローされます。

対象とする .NET フレームワークのバージョンに応じて、UI からデバイス通信を分離するためのオプションがいくつかあります。さまざまなオプションの概要については、「. NET Framework の並列処理と同時実行」を参照してください。スレッド化は低レベルの抽象化であり、タスクや C# のasync および await キーワードなどの高レベルの抽象化を使用する方が簡単で、エラーが発生しにくいことがわかる場合があります。

于 2013-02-16T18:43:40.447 に答える
2

ハードウェアの状態を監視する必要がある場合は、実行時間の長いバックグラウンド スレッドを使用するのが理にかなっていると思います。TaskCreationOptions.LongRunningは適切に見えます。

また、C# の新しい async/await 機能を使用してデバイスと非同期的に対話することは、私にとって理にかなっています。それが役立つかどうかはわかりませんが、ハードウェアの相互作用を通常どのように処理するかを示すスニペットを次に示します (私にとっては、多くの場合、WinUSB デバイスです)。

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 ~);
    }
}
于 2013-02-13T08:32:47.877 に答える