3

I'm doing a program in c# (mono) to print to a fiscal printer (escpos) and it works okay. The problem is that when I print, the program hangs until the buffer I have is cleared. So, as you imagine if I print a couple of images it gets bigger and so it hangs for a while. This is not desirable. I have tested in 2 ways

One way:

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.");             
}

second Way:

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

and neither method is allowing the program to continue the execution. Example: if it starts to print and paper is out it will hang until the printer resumes printing which is not the right way.

Thanks in advance for your time and patience.

spender
  • 117,338
  • 33
  • 229
  • 351
  • 2
    You must provide callback to `BeginWrite` method, which will be invoked on write completion. – Hamlet Hakobyan Apr 11 '13 at 12:16
  • 1
    Why use a `BinaryWriter` when you're writing directly to the underlying stream? Why not just `f = new FileStream(...)` and then call `f.BeginWrite`? – Jim Mischel Apr 11 '13 at 14:43
  • Jim Mischel, what will i earn with that? Im doing in method one a similar procedure. outBuffer.BaseStream.BeginWrite – César Araújo Apr 11 '13 at 15:27
  • The question isn't what you gain from using the `FileStream` directly. The question is what you gain by using `BinaryWriter`. Why create a `FileStream` *and* a `BinaryWriter` when `FileStream` by itself works just fine? – Jim Mischel Apr 11 '13 at 23:07
  • Jim, i need to write binary data, i miss understood your last answer. So i use a binary writter on top of a filestream so i can write binary data to the printer paralel port. Dont know any other good method for it, if u have please share! – César Araújo Apr 15 '13 at 11:25

1 Answers1

1

The problem is that you're making the program wait for the write to complete. If you want it to happen asynchronously, then you need to provide a callback method that will be called when the write is done. For example:

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.
}

That's one way to do it. You should read up on the Asynchronous Programming Model for other options, and pick the one that best suits your needs.

You can also use the Task Parallel Library, which might be a better fit.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • Iv viewed the source code of the mono and i see that "Timeouts are not supported on this stream." wich means i wont have any method good enougth to alert when printer was opened or anything else. – César Araújo Apr 15 '13 at 10:55
  • 1
    @CésarAraújo: Then you probably want to use `ThreadPool.RegisterWaitForSingleObject` to register a wait and a timeout, and then call `Stream.WriteAsync` with a cancellation token to do the write. If the wait signals a timeout, then you can cancel the printing operation. See http://msdn.microsoft.com/en-us/library/hh137799.aspx. Or perhaps the `Task` has some timeout capability. I'm not sure about that. – Jim Mischel Apr 15 '13 at 13:53
  • Iv found a solution. Starting a thread and doing a timeout in the thread seems todo the job. Thanks for all the help. – César Araújo Apr 29 '13 at 15:20