{"id":87,"date":"2006-01-27T16:43:28","date_gmt":"2006-01-27T23:43:28","guid":{"rendered":"http:\/\/kennyw.com\/indigo\/87"},"modified":"2006-01-27T16:43:28","modified_gmt":"2006-01-27T23:43:28","slug":"iduplexsessioncloseoutputsession","status":"publish","type":"post","link":"https:\/\/kennyw.com\/?p=87","title":{"rendered":"IDuplexSession.CloseOutputSession"},"content":{"rendered":"<p>When writing an <code class=\"classname\">IDuplexSessionChannel<\/code>, one of the pieces that needs to be implemented is (as you might expect) <code class=\"classname\">IDuplexSession<\/code>.  <code class=\"classname\">IDuplexSession<\/code> has one additional requirement on top of ISession, and that is the ability to perform a &#8220;half-close&#8221;.  Semantically this is the same as <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/system.net.sockets.socket.shutdown.aspx\">Shutdown(Send)<\/a> in sockets-speak.<\/p>\n<p>When you call <code class=\"classname\">IDuplexSession<\/code><code>.CloseOutputSession()<\/code>, this signals to the other side of the session that it should return null from outstanding and subsequent calls to <code>Receive()<\/code>. CloseOutputSession() is also idempotent (just like <code class=\"classname\">ICommunicationObject<\/code><code>.Close()<\/code> and <code class=\"classname\">ICommunicationObject<\/code><code>.Abort()<\/code>).<\/p>\n<p>CloseOutputSession() is also a little tricky, because it&#8217;s a session method that can interact with the owning <code class=\"classname\">IDuplexSessionChannel<\/code> that owns the session. In particular, if your session lifetime is coupled with your channel lifetime (like it is for TCP and RM and Security):<\/p>\n<ol>\n<li>If CloseOutputSession() is called before channel.Close(), channel.Close() should wait for CloseOutputSession() to finish.<\/li>\n<li>If the channel is in the Created or Opening state, CloseOutputSession() should <code class=\"keyword\">throw new<\/code> <code>InvalidOperationException(...)<\/code>.<\/li>\n<li>If the channel is in the Faulted state, CloseOutputSession() should <code class=\"keyword\">throw new<\/code> <code>CommunicationObjectFaultedException(...)<\/code>.<\/li>\n<li>The channel should fault if CloseOutputSession throws.<\/li>\n<li>channel.Close() should call CloseOutputSession() and then verify that Receive() returns <code class=\"keyword\">null<\/code> (i.e. CloseOutputSession was called from the other side of the session).<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>When writing an IDuplexSessionChannel, one of the pieces that needs to be implemented is (as you might expect) IDuplexSession. IDuplexSession has one additional requirement on top of ISession, and that is the ability to perform a &#8220;half-close&#8221;. Semantically this is the same as Shutdown(Send) in sockets-speak. When you call IDuplexSession.CloseOutputSession(), this signals to the other [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-87","post","type-post","status-publish","format-standard","hentry","category-indigo"],"_links":{"self":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts\/87","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=87"}],"version-history":[{"count":0,"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts\/87\/revisions"}],"wp:attachment":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=87"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=87"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=87"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}