C# 使用FileStream.Read正确关闭应用程序

C# 使用FileStream.Read正确关闭应用程序,c#,filestream,C#,Filestream,在某个地方我打电话 Task.Run(new Action(Read)); 此调用在其他线程中启动任务: private void Read() { while (!cancelToken.IsCancellationRequested) { int bytesReaded = deviceStream.Read(buffer, 0, bufferSize); } } 此线程在读取时阻塞,并尝试从文件中获取一些数据(这不是常见的文件,这是设备)。然后我

在某个地方我打电话

Task.Run(new Action(Read));
此调用在其他线程中启动任务:

private void Read()
{
    while (!cancelToken.IsCancellationRequested)
    {
        int bytesReaded = deviceStream.Read(buffer, 0, bufferSize);
    }
}
此线程在读取时阻塞,并尝试从文件中获取一些数据(这不是常见的文件,这是设备)。然后我关闭应用程序,表单关闭,但应用程序仍在运行。我尝试在deviceStream上关闭并处理,但没有帮助-它仍在等待读取完成。Microsoft不建议中断线程

其主要目标是不间断地读取数据,但数据从设备逐块到达,并且数据块之间的停顿可能很大,因此读取可能会被长时间阻止

问题:有什么方法可以优雅地打断阅读?是否可以实现另一种模式来实现我的目标(可能使用BeginRead/EndRead,但这里读到EndRead也会阻塞,不能被中断)


PS:我在MSDN ReadAsync中看到了新方法,但无法想象如何使用它(我需要重新启动读取)

如果设备流提供ReadTimeout属性,您可以使用它:


也许这对你有帮助:

private void Read()
{
    while (!cancelToken.IsCancellationRequested)
    {
        if(deviceStream.CanRead && deviceStream.Length > 0)
            int bytesReaded = deviceStream.Read(buffer, 0, Math.Min(bufferSize, deviceStream.Length));
    }
}

当然,当您处理时,您需要调用取消请求

它不是FileStream。读取问题,我使用KeWait…函数在驱动程序中阻止了ReadDispatcher。

您能描述什么是deviceStream吗?Crystal ball说它实际上是Close()称之为死锁,向我们显示堆栈跟踪。如果不是,那么您需要为该设备购买更好的设备驱动程序。无论从谁那里获得驱动程序,您都会得到最好的建议。@progpow deviceStream=new FileStream(deviceHandle,FileAccess.ReadWrite,bufferSize,true);@HansPassant未在deviceStream.Read上阻塞,然后调用deviceStream.Close()无阻塞。设备是我的设备驱动程序。可能是我出错,然后开发驱动程序。我只是尝试读取并关闭COM1设备,然后我的应用程序应关闭。此流的CanTimeout属性=false@Vakyob我做了更改,如果您的流支持它,那么它将工作。我看到您的更改,我看到您不了解情况。“阅读”阻止线程,所以下次签入if()将到达,然后发生读取或读取错误。如果没有要读取的数据线程被阻塞,并且此时没有检查。@Vakyob循环在有数据时输入为只读,读取后检查其他一个,如果流没有数据,则跳过If。我做了其他一个更改-流只读缓冲区帧或流中的所有数据。但直到我不知道,是支持还是不支持不是你的流长度属性。抱歉,progpow,我认为你写的是你的理论,而不是实践。CanRead属性只表示流是否支持读取(某些流只能写),它实际上不显示流是否有数据。因此在我的例子中,if(deviceStream.CanRead)始终为true。第二,关于长度属性。读取已以这种方式工作,无需额外检查。如果流中的数据大于缓冲区大小,则它将只读缓冲区大小字节,如果长度小于,则它将读取长度字节并返回ByteReaded=Length。@Vakyob,确定,如果长度==0,则不输入读取,并始终退出
,而
,when cancel调用。奇怪的是,close()和dispose()不释放资源。