我应该使用线程异步访问连接到PCI总线的设备吗?

时间:2013-02-07 16:30:21

标签: c# multithreading asynchronous pci

我有一块硬件通过PCI总线连接到我的PC。 我通过设备驱动程序的.NET包装器访问硬件。

我没有关于设备如何执行PCI的任何规范。这让我想到了第一个问题。

1)通过PCI连接的设备是否能保证以一定的速度传送数据?

2)与设备通信时,我希望我的UI保持响应。在(线程池)线程中启动与设备的通信是一个好主意,或者与访问PCI总线的速度相比,与此相关的开销是否过大?

修改
问题改写了。在漫长的工作日结束时反映太多。
删除了线程成为线程池线程的要求。

3 个答案:

答案 0 :(得分:4)

通常,只要您有机会编写没有线程关联的代码,这通常是个好主意。这样,当它成为响应问题时,您可以自由地关闭UI线程。使用异步方法为此I / O设计API也可以使您的选项以良好的方式保持开放。

如果您不必长时间占用它,那么您所使用的线程是线程池线程还是您自己生成的线程似乎无关紧要。如果你可以做Async I / O,那么线程池线程应该没问题。

答案 1 :(得分:3)

  

通过PCI连接的设备是否可以保证在a   一定的速度?

没有。据我了解,PCI是一个共享总线bus mastering,这个功能允许单个设备暂时使用完整的总线带宽。在non-server environments中,这通常意味着133MB / s的带宽。一旦PCI总线上有几个I / O卡,您就可以看到负载下带宽可能会变得稀缺。行为不当的设备也会对延迟产生不利影响;一些控制器挂起,直到它的驱动器响应I / O,但被授予,这是一种异常情况。

  

与设备通信时,我希望我的用户界面保持不变   响应。开始与网络沟通是一个好主意   (线程池)线程中的设备,或者是与之相关的开销   与访问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)更容易且更不容易出错。

答案 2 :(得分:2)

我认为当您需要监视硬件状态时,使用长时间运行的后台线程是有意义的。 TaskCreationOptions.LongRunning看起来很合适。

此外,使用C#的新异步/等待功能与设备异步交互对我来说很有意义。 我不确定它会有所帮助,但这里有一个片段来说明我通常如何处理硬件交互(对我而言,它通常是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 ~);
    }
}