c# - Convert BeginRead loop into ReadAsync and cancel on demand -
i trying build 2 applications communicate on rdp each other. have basic communication, optimize code , remove exceptions.
on server i'm opening filestream , when send client i'm reading using beginread
:
public void connect() { mhandle = native.wtsvirtualchannelopen(intptr.zero, -1, channel_name); task.factory.startnew(() => { intptr temppointer = intptr.zero; uint pointerlen = 0; if (native.wtsvirtualchannelquery(mhandle, wtsvirtualclass.wtsvirtualfilehandle, out temppointer, ref pointerlen)) { intptr realpointer = marshal.readintptr(temppointer); native.wtsfreememory(temppointer); var filehandle = new safefilehandle(realpointer, false); filestream = new filestream(filehandle, fileaccess.readwrite, 0x640, true); var os = new objectstate(); os.rdpstream = filestream; filestream.beginread(os.buffer, 0, 8, callback, os); } }); }
and callback:
private void callback(iasyncresult iar) { if (iar.iscompleted || iar.completedsynchronously) { var os = iar.asyncstate objectstate; int readed = 0; seek { readed = os.rdpstream.endread(iar); } grab (ioexception ex) { messagebox.show(ex.message); } if (readed != 0) { switch (os.state) { case filedownloadstatus.length: os.length = bitconverter.toint32(os.buffer, 0); os.state = filedownloadstatus.body; os.rdpstream.beginread(os.buffer, 0, os.length, callback, os); break; case filedownloadstatus.body: var message = encoding.utf8.getstring(os.buffer, 0, readed); debug.writeline(message); var newos = new objectstate {rdpstream = os.rdpstream}; os.rdpstream.beginread(newos.buffer, 0, 8, callback, newos); break; } } } }
and needed items:
enum filedownloadstatus { length, body, } class objectstate { public int length = 0; public filedownloadstatus state = filedownloadstatus.length; public byte[] buffer = new byte[0x640]; public filestream rdpstream = null; }
unfortunately when seek close application exception system.operationcanceledexception
.
i convert readasync because utilize cancelationtoken, must upgrade .net 4.5.
i found similar question cancelationtoken, it's written in f# , need c#.
so question is: how can stop beginread or transform code .net 4.5 , utilize readasync?
converting async/await:
replace filestream.beginread(os.buffer, 0, 8, callback, os);
with:
task<int> task = filestream.readasync(os.buffer, 0, 8, canceltoken); seek { await task; await callback(os, task); } grab (ioexception ex) { // todo: unpack task exception , display correctly messagebox.show(ex.message); }
note assume have new canceltoken
variable containing cancelationtoken
object. suppose might store in objectstate
object, it's readily available you'll want phone call readasync()
.
change first part of callback()
method (before if (readed != 0)
statement) this:
private async task callback(objectstate os, task<int> task) { if (task.status != taskstatus.canceled) { int readed = task.result;
i.e. replace of code before if (readed != 0)
statement above, changing method declaration above.
apply similar changes code within callback()
method, phone call beginread()
. i.e. utilize readasync
, utilize await
returned task<int>
, pass task<int>
callback when await
completes, calling await
well. (you should able have 1 try/catch block in connect()
method...exceptions occurring in continuations should propagate try/catch block).
note in add-on alter callback()
method declaration, need alter void connect()
method declaration it's async task connect()
. note forcefulness callers become async
methods , utilize await
when calling (and on, phone call chain until ui event handler, can async
, utilize await
, while legitimately beingness void
method), or deal returned task
straight (not recommended, since means negating benefit of async/await idiom).
if maintain using beginread()
method instead, far can recall way cancel close filestream
object (which cause operation finish objectdisposedexception
).
finally note: i'm not familiar plenty rdp i/o comment on utilize of byte-count result async reads. in other contexts, bad thought assume have read many bytes asked for. typically, have maintain looping, reading info until have many bytes need.
c# asynchronous filestream
No comments:
Post a Comment