{"id":2991,"date":"2015-02-04T13:00:13","date_gmt":"2015-02-04T13:00:13","guid":{"rendered":"http:\/\/writeasync.net\/?p=2991"},"modified":"2015-02-03T22:37:24","modified_gmt":"2015-02-03T22:37:24","slug":"interfaces-sync-or-async","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=2991","title":{"rendered":"Interfaces: sync or async?"},"content":{"rendered":"<p>Given an extensible interface, how should one decide whether to define synchronous or asynchronous methods? (Note that in this case I mean <a href=\"http:\/\/en.wikipedia.org\/wiki\/Interface_(computing)#Software_interfaces\">interface in the general software engineering sense<\/a>, so feel free to substitute base class, <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/z4zxe9k8.aspx\">exported DLL function<a>, function pointer\/delegate, etc. as desired.)<\/p>\n<p>There are no hard and fast rules beyond the obvious &#8212; primarily <a href=\"http:\/\/channel9.msdn.com\/Series\/Three-Essential-Tips-for-Async\/Tip-2-Distinguish-CPU-Bound-work-from-IO-bound-work\">I\/O-bound<\/a> interactions (e.g. network or file access) should be async. Things get more hazy in the subtle cases where <em>sometimes<\/em> I\/O is involved, but not always.<\/p>\n<p>Imagine a web testing library which provides an extensible <code>ResponseValidator<\/code> class. A user could override the <code>Validate(<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/vstudio\/system.net.httpwebresponse(v=vs.110).aspx\">HttpWebResponse<\/a>)<\/code> method to implement a custom validation task. Most use cases would involve static assertions, for instance to ensure the header contains a properly formatted <a href=\"http:\/\/en.wikipedia.org\/wiki\/HTTP_ETag\">ETag<\/a>. But what if you needed to send the response text to an <a href=\"http:\/\/xspell.tk\/?page=api\">online spelling API<\/a>? Technically you&#8217;d want to use async to manage the additional web request, but the interface here does not support this. Given that there is an acceptable alternative (e.g. using a locally installed <a href=\"http:\/\/aspell.net\/\">spell check library<\/a>) it would not be worth forcing an async signature for something which would rarely, if ever, be needed.<\/p>\n<p>Now consider a system with a plug-in model that offers varying degrees of isolation such that the host could potentially be in a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Process_isolation\">separate process<\/a>. To provide a unified programming model, it would possible to hide all the details and allow clients to interact with plug-ins as if they were local objects (think <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms735103.aspx\">WCF proxies<\/a> or <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms683835(v=vs.85).aspx\">COM servers<\/a>). This approach sounds quite convenient but happens to run afoul of <a href=\"http:\/\/martinfowler.com\/articles\/distributed-objects-microservices.html\">Martin Fowler&#8217;s First Law of Distributed Objects<\/a>: &#8220;don&#8217;t distribute your objects.&#8221; As Fowler points out, there are too many encapsulation-breaking realities to make this a recommended approach; processes can crash, <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa365574(v=vs.85).aspx\">communication channels<\/a> can break, and everything is far slower than a truly local method call. If you must do this, consider a compromise similar to <a href=\"http:\/\/blogs.msdn.com\/b\/mjm\/archive\/2005\/05\/04\/414793.aspx\">WCF&#8217;s client-side async contracts<\/a>: define a synchronous interface for the plug-in implementer but a fully async interface for the plug-in client.<\/p>\n<p>What about a case where I\/O is certainly involved but a &#8220;defective&#8221; implementation forces synchronous behavior? A real-life example might be a system that interacts with multiple work item trackers &#8212; <a href=\"\">TFS<\/a>, <a href=\"https:\/\/developer.atlassian.com\/display\/JIRADEV\/JIRA+REST+APIs\">JIRA<\/a>, <a href=\"https:\/\/trello.com\/docs\/\">Trello<\/a>, <a href=\"http:\/\/dev.agilezen.com\/\">AgileZen<\/a>, etc. All items in that list expose a REST API except TFS, whose commonly exposed <a href=\"http:\/\/blogs.msdn.com\/b\/mvpawardprogram\/archive\/2011\/09\/26\/getting-up-and-running-with-the-tfs-2010-object-model.aspx\">object model is simple but fully synchronous<\/a> (though there is an <a href=\"http:\/\/blogs.msdn.com\/b\/briankel\/archive\/2013\/01\/07\/odata-service-for-team-foundation-server-v2.aspx\">OData service beta release<\/a>). Should the lone sync API binding force you into a totally sync implementation for all? Probably not. You can begrudgingly use <code><a href=\"http:\/\/blogs.msdn.com\/b\/pfxteam\/archive\/2011\/10\/24\/10229468.aspx\">Task.Run<\/a><\/code> to &#8220;fix&#8221; the blocking calls until a better API emerges. Otherwise you risk causing a huge ripple on the order of a complete redesign if you later need to go full async.<\/p>\n<p>Is it ever acceptable to provide <strong>both<\/strong> async and sync methods? This might make sense in &#8220;legacy&#8221; libraries, especially those that were built in the <code>IAsyncResult<\/code> days before async was an accessible and familiar practice. Think the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.io.stream_members(v=vs.71).aspx\">Stream API in .NET, which arrived back in .NET 1.0<\/a>. To avoid confusion and promote better practices, modern apps should <em>not<\/em> provide synchronous APIs for I\/O-centric operations.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Given an extensible interface, how should one decide whether to define synchronous or asynchronous methods? (Note that in this case I mean interface in the general software engineering sense, so feel free to substitute base class, exported DLL function, function&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21,91],"tags":[],"class_list":["post-2991","post","type-post","status-publish","format-standard","hentry","category-async","category-design"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/2991","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2991"}],"version-history":[{"count":0,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/2991\/revisions"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2991"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}