c# - Async Read Synchronization -
it seems can not find elegant solution synchronization of code below. remember once did similar thing mind blank.
i need protect no 2 threads read socket, 1 thread waits on beginread. when use mutex in way, syncronizationerror.
class program { tcpclient client = new tcpclient(); public readonly object loker = new object(); public void beginread() { if (!mutex.tryenter(loker)) { return; } client.getstream().beginread(..., read_callback); } private void read_callback(iasyncresult ar) { client.getstream().endread(ar); mutex.exit(loker); beginread(); } static void main(string[] args) { beginread(); } }
what need here synchronization method designed asynchronous, rather synchronous, critical sections. want able run code asynchronously after code able take out lock rather making asynchronous method use synchronous locking mechanisms. synchronous mechanisms expect lock released same thread taken out on; asynchronous operation doesn't make sense. semaphoreslim
designed support asynchronous synchronization.
private tcpclient client = new tcpclient(); private semaphoreslim semaphore = new semaphoreslim(1, 1); public void beginread() { semaphore.waitasync() .continuewith(t => client.getstream() .beginread(null, 0, 0, read_callback, null)); } private void read_callback(iasyncresult ar) { client.getstream().endread(ar); semaphore.release(); beginread(); }
you have option of using tpl refactor program rather dramatically.
to you'd need create method generates task
based on asynchronous operation you're interested in, rather style of asynchrony:
public static task<int> whenread( networkstream stream, byte[] buffer, int offset, int size) { var tcs = new taskcompletionsource<int>(); stream.beginread(buffer, offset, size, result => { tcs.trysetresult(stream.endread(result)); }, null); return tcs.task; }
but once have program becomes far easier work with:
public async void beginread() { while (true) { await semaphore.waitasync(); int result = await client.getstream().whenread(null, 0, 0); semaphore.release(); dostuffwithresult(result); } }
Comments
Post a Comment