Thursday, 15 August 2013

c# - Convert BeginRead loop into ReadAsync and cancel on demand -



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