【问题标题】:Nonblocking io using BinaryWriter to write to usblp0使用 BinaryWriter 写入 usblp0 的非阻塞 io
【发布时间】:2013-04-11 11:54:06
【问题描述】:

我正在用 c# (mono) 编写一个程序来打印到财务打印机 (escpos),它工作正常。问题是当我打印时,程序会挂起,直到我拥有的缓冲区被清除。因此,正如您想象的那样,如果我打印几张图像,它会变得更大,因此会挂起一段时间。这是不可取的。我已经通过两种方式进行了测试

一种方式

BinaryWriter outBuffer;
this.outBuffer = new BinaryWriter(new  FileStream (this.portName,System.IO.FileMode.Open));
.... apend bytes to buffer...
IAsyncResult asyncResult = null; 
asyncResult = outBuffer.BaseStream.BeginWrite(buffer,offset,count,null,null);
asyncResult.AsyncWaitHandle.WaitOne(100);
outBuffer.BaseStream.EndWrite(asyncResult); // Last step to the 'write'.
if (!asyncResult.IsCompleted) // Make sure the write really completed.
{
throw new IOException("Writte to printer failed.");             
}

第二种方式

BinaryWriter outBuffer;
this.outBuffer = new BinaryWriter(new  FileStream (this.portName,System.IO.FileMode.Open));
.... apend bytes to buffer...
outBuffer.Write(buffer, 0, buffer.Length);

这两种方法都不允许程序继续执行。示例:如果它开始打印并且纸张用完,它将一直挂起,直到打印机恢复打印,这是不正确的方式。

提前感谢您的时间和耐心。

【问题讨论】:

  • 您必须为BeginWrite方法提供回调,该方法将在写入完成时调用。
  • 为什么在直接写入底层流时使用BinaryWriter?为什么不直接f = new FileStream(...),然后打电话给f.BeginWrite
  • 吉姆·米歇尔,我能用它赚到什么?我在方法一中做类似的程序。 outBuffer.BaseStream.BeginWrite
  • 问题不在于直接使用FileStream 会获得什么。问题是使用BinaryWriter 可以获得什么。当FileStream 本身就可以正常工作时,为什么还要创建FileStream BinaryWriter
  • 吉姆,我需要写二进制数据,我想念你的最后一个答案。所以我在文件流之上使用二进制写入器,这样我就可以将二进制数据写入打印机并行端口。不知道还有什么好方法,如果有请分享!

标签: c# binarywriter


【解决方案1】:

问题是您让程序等待写入完成。如果您希望它异步发生,那么您需要提供一个回调方法,该方法将在写入完成时调用。例如:

asyncResult = outBuffer.BaseStream.BeginWrite(buffer,offset,count,WriteCallback,outBuffer);

private void WriteCallback(IAsyncResult ar)
{
    var buff = (BinaryWriter)ar.AsyncState;
    // following will throw an exception if there was an error
    var bytesWritten = buff.BaseStream.EndWrite(ar);

    // do whatever you need to do to notify the program that the write completed.
}

这是一种方法。您应该阅读Asynchronous Programming Model 以了解其他选项,然后选择最适合您需求的选项。

您也可以使用Task Parallel Library,这可能更合适。

【讨论】:

  • 我查看了单声道的源代码,我看到“此流不支持超时”。这意味着当打印机打开或其他任何东西时,我不会有任何好的方法来提醒。
  • @CésarAraújo:那么您可能想使用ThreadPool.RegisterWaitForSingleObject 来注册等待和超时,然后使用取消令牌调用Stream.WriteAsync 来进行写入。如果等待发出超时信号,则您可以取消打印操作。见msdn.microsoft.com/en-us/library/hh137799.aspx。或者Task 可能有一些超时功能。我不确定。
  • 我找到了解决方案。启动一个线程并在线程中执行超时似乎完成了这项工作。感谢所有的帮助。
猜你喜欢
  • 2012-03-04
  • 1970-01-01
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多