I am writing a simple console application that does only the following:
1. Query the database for some data.
2. Process this data.
3. Update the database.
I wrote the code, which consists only of the Main method, like the following:
class Program
{
static void Main(string[] args)
{
try
{
var dbContext = new MyDatabaseContext();
var dbRecord = dbContext.MyTable.First(r => r.Status == 1);
// Do some work
dbRecord.Status = 2;
dbContext.SaveChanges();
}
catch(Exception)
{
// left empty
}
}
}
A colleague of mine told me that I must enclose the code within a "using" statement to close the connection between the application and the database server, like the following:
class Program
{
static void Main(string[] args)
{
try
{
using(var dbContext = new MyDatabaseContext())
{
var dbRecord = dbContext.MyTable.First(r => r.Status == 1);
// Do some work
dbRecord.Status = 2;
dbContext.SaveChanges();
}
}
catch(Exception)
{
// left empty
}
}
}
I know the importance of disposing an "IDisposable" object, before leaving a scope or when the object is no longer needed, to avoid memory leak and to release resources.
But my understanding is, in my case, the program already ends and I don't need to explicitly dispose the DbContext as no connection will exist between the application and the database server after the application ends.
So, I need to answer the following:
1.Is it important, in my case, to dispose the DbContext object before the program exits?
2. Will the connection be still open even after closing the program (Normally, with an exception, or closed by the user)?
3. What will happen if I don't use the "using" statement?
I will be thankful if you provide the answers with official references.
Please note that my concern is memory and resource leaks. Data loss is not my concern for now.
To answer to your 3 questions:
EF tutorial docs say: "...Also, in most common cases, not calling Dispose at all (either implicitly or explicitly) isn't harmful.". I don't trust most common cases. It's a best practice to do it, and I would. By doing it, you are implicitly sure that every resource your context is using is properly released because the maintainers of this framework say so.
No, no connection opened because the object holding the connection lives in your program's memory. After the OS chooses to kill the process, there is no more pointer to that connection object. If it's still in memory, it's unreachable so it's like it does not exist. I don't know if Windows implements some strange global connection pooling but, if so, it would be OS-specific and I would never rely on that.
The using statement defines a scope at the end of which an object will be disposed. So, it translates in implicitly calling the dispose method when the end of the using block is reached. It's cosmetic and helps you better define scopes in your code.
System.Net.Http.HttpClient and System.Net.Http.HttpClientHandler in .NET Framework 4.5 implement IDisposable (via System.Net.Http.HttpMessageInvoker).
The using statement documentation says:
As a rule, when you use an IDisposable object, you should declare and
instantiate it in a using statement.
This answer uses this pattern:
var baseAddress = new Uri("http://example.com");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("foo", "bar"),
new KeyValuePair<string, string>("baz", "bazinga"),
});
cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value"));
var result = client.PostAsync("/test", content).Result;
result.EnsureSuccessStatusCode();
}
But the most visible examples from Microsoft don't call Dispose() either explicitly or implicitly. For instance:
The original blog article announcing the relase of HttpClient.
The actual MSDN documentation for HttpClient.
BingTranslateSample
GoogleMapsSample
WorldBankSample
In the announcement's comments, someone asked the Microsoft employee:
After checking your samples, I saw that you didn't perform the dispose
action on HttpClient instance. I have used all instances of HttpClient
with using statement on my app and I thought that it is the right way
since HttpClient implements the IDisposable interface. Am I on the
right path?
His answer was:
In general that is correct although you have to be careful with
"using" and async as they dont' really mix in .Net 4, In .Net 4.5 you
can use "await" inside a "using" statement.
Btw, you can reuse the same HttpClient as many times are [as] you like so
typically you won't create/dispose them all the time.
The second paragraph is superfluous to this question, which is not concerned about how many times you can use an HttpClient instance, but about if it is necessary to dispose it after you no longer need it.
(Update: in fact that second paragraph is the key to the answer, as provided below by #DPeden.)
So my questions are:
Is it necessary, given the current implementation (.NET Framework 4.5), to call Dispose() on HttpClient and HttpClientHandler instances? Clarification: by "necessary" I mean if there are any negative consequences for not disposing, such as resource leakage or data corruption risks.
If it's not necessary, would it be a "good practice" anyway, since they implement IDisposable?
If it's necessary (or recommended), is this code mentioned above implementing it safely (for .NET Framework 4.5)?
If these classes don't require calling Dispose(), why were they implemented as IDisposable?
If they require, or if it's a recommended practice, are the Microsoft examples misleading or unsafe?
The general consensus is that you do not (should not) need to dispose of HttpClient.
Many people who are intimately involved in the way it works have stated this.
See Darrel Miller's blog post and a related SO post: HttpClient crawling results in memory leak for reference.
I'd also strongly suggest that you read the HttpClient chapter from Designing Evolvable Web APIs with ASP.NET for context on what is going on under the hood, particularly the "Lifecycle" section quoted here:
Although HttpClient does indirectly implement the IDisposable
interface, the standard usage of HttpClient is not to dispose of it
after every request. The HttpClient object is intended to live for as
long as your application needs to make HTTP requests. Having an object
exist across multiple requests enables a place for setting
DefaultRequestHeaders and prevents you from having to re-specify
things like CredentialCache and CookieContainer on every request as
was necessary with HttpWebRequest.
Or even open up DotPeek.
The current answers are a bit confusing and misleading, and they are missing some important DNS implications. I'll try to summarize where things stand clearly.
Generally speaking most IDisposable objects should ideally be disposed when you are done with them, especially those that own Named/shared OS resources. HttpClient is no exception, since as Darrel Miller points out it allocates cancellation tokens, and request/response bodies can be unmanaged streams.
However, the best practice for HttpClient says you should create one instance and reuse it as much as possible (using its thread-safe members in multi-threaded scenarios). Therefore, in most scenarios you'll never dispose of it simply because you will be needing it all the time.
The problem with re-using the same HttpClient "forever" is that the underlying HTTP connection might remain open against the originally DNS-resolved IP, regardless of DNS changes. This can be an issue in scenarios like blue/green deployment and DNS-based failover. There are various approaches for dealing with this issue, the most reliable one involving the server sending out a Connection:close header after DNS changes take place. Another possibility involves recycling the HttpClient on the client side, either periodically or via some mechanism that learns about the DNS change. See https://github.com/dotnet/corefx/issues/11224 for more information (I suggest reading it carefully before blindly using the code suggested in the linked blog post).
Since it doesn't appear that anyone has mentioned it here yet, the new best way to manage HttpClient and HttpClientHandler in .NET Core >=2.1 and .NET 5.0+ is using HttpClientFactory.
It solves most of the aforementioned issues and gotchas in a clean and easy-to-use way. From Steve Gordon's great blog post:
Add the following packages to your .Net Core (2.1.1 or later) project:
Microsoft.AspNetCore.All
Microsoft.Extensions.Http
Add this to Startup.cs:
services.AddHttpClient();
Inject and use:
[Route("api/[controller]")]
public class ValuesController : Controller
{
private readonly IHttpClientFactory _httpClientFactory;
public ValuesController(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
[HttpGet]
public async Task<ActionResult> Get()
{
var client = _httpClientFactory.CreateClient();
var result = await client.GetStringAsync("http://www.google.com");
return Ok(result);
}
}
Explore the series of posts in Steve's blog for lots more features.
In my understanding, calling Dispose() is necessary only when it's locking resources you need later (like a particular connection). It's always recommended to free resources you're no longer using, even if you don't need them again, simply because you shouldn't generally be holding onto resources you're not using (pun intended).
The Microsoft example is not incorrect, necessarily. All resources used will be released when the application exits. And in the case of that example, that happens almost immediately after the HttpClient is done being used. In like cases, explicitly calling Dispose() is somewhat superfluous.
But, in general, when a class implements IDisposable, the understanding is that you should Dispose() of its instances as soon as you're fully ready and able. I'd posit this is particularly true in cases like HttpClient wherein it's not explicitly documented as to whether resources or connections are being held onto/open. In the case wherein the connection will be reused again [soon], you'll want to forgo Dipose()ing of it -- you're not "fully ready" in that case.
See also:
IDisposable.Dispose Method and When to call Dispose
Short answer: No, the statement in the currently accepted answer is NOT accurate: "The general consensus is that you do not (should not) need to dispose of HttpClient".
Long answer: BOTH of the following statements are true and achieveable at the same time:
"HttpClient is intended to be instantiated once and re-used throughout the life of an application", quoted from official documentation.
An IDisposable object is supposed/recommended to be disposed.
And they DO NOT NECESSARILY CONFLICT with each other. It is just a matter of how you organize your code to reuse an HttpClient AND still dispose it properly.
An even longer answer quoted from my another answer:
It is not a coincidence to see people
in some blog posts blaming how HttpClient 's IDisposable interface
makes them tend to use the using (var client = new HttpClient()) {...} pattern
and then lead to exhausted socket handler problem.
I believe that comes down to an unspoken (mis?)conception:
"an IDisposable object is expected to be short-lived".
HOWEVER, while it certainly looks like a short-lived thing when we write code in this style:
using (var foo = new SomeDisposableObject())
{
...
}
the official documentation on IDisposable
never mentions IDisposable objects have to be short-lived.
By definition, IDisposable is merely a mechanism to allow you to release unmanaged resources.
Nothing more. In that sense, you are EXPECTED to eventually trigger the disposal,
but it does not require you to do so in a short-lived fashion.
It is therefore your job to properly choose when to trigger the disposal,
base on your real object's life cycle requirement.
There is nothing stopping you from using an IDisposable in a long-lived way:
using System;
namespace HelloWorld
{
class Hello
{
static void Main()
{
Console.WriteLine("Hello World!");
using (var client = new HttpClient())
{
for (...) { ... } // A really long loop
// Or you may even somehow start a daemon here
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
With this new understanding, now we revisit that blog post,
we can clearly notice that the "fix" initializes HttpClient once but never dispose it,
that is why we can see from its netstat output that,
the connection remains at ESTABLISHED state which means it has NOT been properly closed.
If it were closed, its state would be in TIME_WAIT instead.
In practice, it is not a big deal to leak only one connection open after your entire program ends,
and the blog poster still see a performance gain after the fix;
but still, it is conceptually incorrect to blame IDisposable and choose to NOT dispose it.
Dispose() calls the code below, which closes the connections opened by the HttpClient instance. The code was created by decompiling with dotPeek.
HttpClientHandler.cs - Dispose
ServicePointManager.CloseConnectionGroups(this.connectionGroupName);
If you don't call dispose then ServicePointManager.MaxServicePointIdleTime, which runs by a timer, will close the http connections. The default is 100 seconds.
ServicePointManager.cs
internal static readonly TimerThread.Callback s_IdleServicePointTimeoutDelegate = new TimerThread.Callback(ServicePointManager.IdleServicePointTimeoutCallback);
private static volatile TimerThread.Queue s_ServicePointIdlingQueue = TimerThread.GetOrCreateQueue(100000);
private static void IdleServicePointTimeoutCallback(TimerThread.Timer timer, int timeNoticed, object context)
{
ServicePoint servicePoint = (ServicePoint) context;
if (Logging.On)
Logging.PrintInfo(Logging.Web, SR.GetString("net_log_closed_idle", (object) "ServicePoint", (object) servicePoint.GetHashCode()));
lock (ServicePointManager.s_ServicePointTable)
ServicePointManager.s_ServicePointTable.Remove((object) servicePoint.LookupString);
servicePoint.ReleaseAllConnectionGroups();
}
If you haven't set the idle time to infinite then it appears safe not to call dispose and let the idle connection timer kick-in and close the connections for you, although it would be better for you to call dispose in a using statement if you know you are done with an HttpClient instance and free up the resources faster.
In my case, I was creating an HttpClient inside a method that actually did the service call. Something like:
public void DoServiceCall() {
var client = new HttpClient();
await client.PostAsync();
}
In an Azure worker role, after repeatedly calling this method (without disposing the HttpClient), it would eventually fail with SocketException (connection attempt failed).
I made the HttpClient an instance variable (disposing it at the class level) and the issue went away. So I would say, yes, dispose the HttpClient, assuming its safe (you don't have outstanding async calls) to do so.
In typical usage (responses<2GB) it is not necessary to Dispose the HttpResponseMessages.
The return types of the HttpClient methods should be Disposed if their Stream Content is not fully Read. Otherwise there is no way for the CLR to know those Streams can be closed until they are garbage collected.
If you are reading the data into a byte[] (e.g. GetByteArrayAsync) or string, all data is read, so there is no need to dispose.
The other overloads will default to reading the Stream up to 2GB (HttpCompletionOption is ResponseContentRead, HttpClient.MaxResponseContentBufferSize default is 2GB)
If you set the HttpCompletionOption to ResponseHeadersRead or the response is larger than 2GB, you should clean up. This can be done by calling Dispose on the HttpResponseMessage or by calling Dispose/Close on the Stream obtained from the HttpResonseMessage Content or by reading the content completely.
Whether you call Dispose on the HttpClient depends on whether you want to cancel pending requests or not.
If you want to dispose of HttpClient, you can if you set it up as a resource pool. And at the end of your application, you dispose your resource pool.
Code:
// Notice that IDisposable is not implemented here!
public interface HttpClientHandle
{
HttpRequestHeaders DefaultRequestHeaders { get; }
Uri BaseAddress { get; set; }
// ...
// All the other methods from peeking at HttpClient
}
public class HttpClientHander : HttpClient, HttpClientHandle, IDisposable
{
public static ConditionalWeakTable<Uri, HttpClientHander> _httpClientsPool;
public static HashSet<Uri> _uris;
static HttpClientHander()
{
_httpClientsPool = new ConditionalWeakTable<Uri, HttpClientHander>();
_uris = new HashSet<Uri>();
SetupGlobalPoolFinalizer();
}
private DateTime _delayFinalization = DateTime.MinValue;
private bool _isDisposed = false;
public static HttpClientHandle GetHttpClientHandle(Uri baseUrl)
{
HttpClientHander httpClient = _httpClientsPool.GetOrCreateValue(baseUrl);
_uris.Add(baseUrl);
httpClient._delayFinalization = DateTime.MinValue;
httpClient.BaseAddress = baseUrl;
return httpClient;
}
void IDisposable.Dispose()
{
_isDisposed = true;
GC.SuppressFinalize(this);
base.Dispose();
}
~HttpClientHander()
{
if (_delayFinalization == DateTime.MinValue)
_delayFinalization = DateTime.UtcNow;
if (DateTime.UtcNow.Subtract(_delayFinalization) < base.Timeout)
GC.ReRegisterForFinalize(this);
}
private static void SetupGlobalPoolFinalizer()
{
AppDomain.CurrentDomain.ProcessExit +=
(sender, eventArgs) => { FinalizeGlobalPool(); };
}
private static void FinalizeGlobalPool()
{
foreach (var key in _uris)
{
HttpClientHander value = null;
if (_httpClientsPool.TryGetValue(key, out value))
try { value.Dispose(); } catch { }
}
_uris.Clear();
_httpClientsPool = null;
}
}
var handler = HttpClientHander.GetHttpClientHandle(new Uri("base url")).
HttpClient, as an interface, can't call Dispose().
Dispose() will be called in a delayed fashion by the Garbage Collector.
Or when the program cleans up the object through its destructor.
Uses Weak References + delayed cleanup logic so it remains in use so long as it is being reused frequently.
It only allocates a new HttpClient for each base URL passed to it. Reasons explained by Ohad Schneider answer below. Bad behavior when changing base url.
HttpClientHandle allows for Mocking in tests
Using dependency injection in your constructor makes managing the lifetime of your HttpClient easier - taking the lifetime managemant outside of the code that needs it and making it easily changable at a later date.
My current preference is to create a seperate http client class that inherits from HttpClient once per target endpoint domain and then make it a singleton using dependency injection. public class ExampleHttpClient : HttpClient { ... }
Then I take a constructor dependency on the custom http client in the service classes where I need access to that API. This solves the lifetime problem and has advantages when it comes to connection pooling.
You can see a worked example in related answer at https://stackoverflow.com/a/50238944/3140853
No, don't create a new one on every request (even if you dispose of the old ones). You will cause the server itself (not just the application) to crash because of port exhaustion at the network level on the Operating System!
Please take a read on my answer to a very similar question posted below. It should be clear that you should treat HttpClient instances as singletons and re-used across requests.
What is the overhead of creating a new HttpClient per call in a WebAPI client?
I think one should use singleton pattern to avoid having to create instances of the HttpClient and closing it all the time. If you are using .Net 4.0 you could use a sample code as below. for more information on singleton pattern check here.
class HttpClientSingletonWrapper : HttpClient
{
private static readonly Lazy<HttpClientSingletonWrapper> Lazy= new Lazy<HttpClientSingletonWrapper>(()=>new HttpClientSingletonWrapper());
public static HttpClientSingletonWrapper Instance {get { return Lazy.Value; }}
private HttpClientSingletonWrapper()
{
}
}
Use the code as below.
var client = HttpClientSingletonWrapper.Instance;
What are the ramifications of not calling .Dispose() on an OrganizationServiceProxy object?
Sometimes, during testing, code crashes before the object can be disposed; does this mean that a service channel is left open for all eternity?
I have the same question about OrganizationServiceContext, which I had not been disposing until reading this today.
/* Synchronizes with CRM * */
public class CRMSync
{
[ThreadStatic] // ThreadStatic ensures that each thread gets a copy of these fields
private static OrganizationServiceProxy service;
[ThreadStatic]
private static Context linq;
/* Tries to connect to CRM and return false if failure - credentials arguments */
private bool Connect(string username = #"username", string password = "password", string uri = #"orgUrl/XRMServices/2011/Organization.svc")
{
try
{
var cred = new ClientCredentials();
cred.UserName.UserName = username;
cred.UserName.Password = password;
service = new OrganizationServiceProxy(new Uri(uri), null, cred, null);
service.EnableProxyTypes(); // this has to happen to allow LINQ early bound queries
linq = new Context(service);
var who = new Microsoft.Crm.Sdk.Messages.WhoAmIRequest(); // used to test the connection
var whoResponse = (Microsoft.Crm.Sdk.Messages.WhoAmIResponse)service.Execute(who); // this fails if not connected
}
catch (Exception e)
{
Log(e.Message); // Write to Event Log
return false;
}
return true;
}
}
Is there another way to use the same OrganizationServiceContext and OrganizationServiceProxy in multiple methods?
I plan to use this destructor to dispose the OrganizationServiceProxy and OrganizationServiceContext:
~CRMSync()
{
if (service != null)
service.Dispose();
if(linq!=null)
linq.Dispose();
}
EDIT
This is the method that is called by the service OnStart
/* Called by CRMAUX.OnStart when it is time to start the service */
public async void Start()
{
this.ProcessCSVFiles(); // Creates a ThreadPool thread that processes some CSV files
this.ProcessCases(); // Imports cases into CRM from a db (on this thread)
var freq = 0;
ConfigurationManager.RefreshSection("appSettings");
var parse = int.TryParse(ConfigurationManager.AppSettings["Frequency"], out freq);
await System.Threading.Tasks.Task.Delay((parse) ? freq * 1000 * 60 : 15000 * 60); // 15 minutes default or user defined
Start(); // Start again after the wait above
}
This is the Windows service
public partial class CRMAUX : ServiceBase
{
private CRMSync crmSync;
public CRMAUX()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
ConfigurationManager.RefreshSection("userSettings"); // Get the current config file so that the cached one is not useds
if (TestConfigurationFile())
{
crmSync = new CRMSync();
Thread main = new Thread(crmSync.Start);
main.IsBackground = true;
main.Start();
}
else //The configuration file is bad
{
Stop(); // inherited form ServiceBase
return;
}
}
protected override void OnStop()
{
}
/* Checks the configuration file for the necessary keys */
private bool TestConfigurationFile()...
}
The OrganizationServiceProxy is a wrapper around a WCF Channel which utilises unmanaged resources (sockets etc.).
A class (our proxy) that implements IDisposable is essentially stating that it will be accessing unmanaged resources and you should therefore explicitly tell it when you're finished with it rather than just allowing it to go out of scope. This will allow it to release the handles to those resources and free them up for use elsewhere. Unfortunately our code isn't the only thing running on the server!
Unmanaged resources are finite and expensive (SQL connections are the classic example). If your code executes correctly but you don't explicitly call dispose then the clean up of those resources will be non-deterministic which is a fancy way of saying the garbage collector will only call dispose on those managed objects "eventually", which will as stated in turn clean up the unmanaged resources they're holding onto. This will hurt scalability of your application and any other services running on the same hardware that might be in contention with you for those resources. That's the best case scenario, if an exception occurs at any point in the stack subsequent to those resources being acquired they will not be released, ergo a memory leak and fewer resources available for use elsewhere.
Wrapping your code in a using statement is syntactic sugar as this compiles down to the proxy being wrapped in a try/finally with the dispose being called in the finally.
In terms of using the proxy/context across multiple methods you should take a look at the Unit of Work pattern. The OrganizationServiceContext is exactly that, something that you apply changes to over the course of a request (likely across multiple method calls) and then submit to the datastore (CRM) at the end when done, in our case using context.SaveChanges().
Where are you using this code as I'm curious to know what you're looking to achieve with the use of the [ThreadStatic] attribute? If it's within an IIS hosted application I don't think you'll see any benefit as you don't manage the thread pool so the proxy still only has a lifetime matching the HttpRequest. If this is the case there are several better ways of managing the lifetime of these objects, dependency injection frameworks and a HttpRequest lifetime behaviour being the obvious one.
If your app crashes, the operating system will automatically reclaim all your resources, i.e. close all network ports, files etc. So there's nothing kept open forever. Of course, on the server side something unexpected can happen if it is not handled properly and the app crashes in the middle of a request. But that's what transactions are for, such that the state of the server data is always consistent.
I have a very interesting scenario where I would like a class to inform another entity it has been destroyed; however, its not doing what I want it too.
The Problem
The deconstructor, for some reason does not do what its supposed to do.
The Question
Why is the destructor not being invoked and make sure that it does do its necessary clean up.
The Code
So here we have the informer ~
class Connection
{
public const int Port = 50000;// Can be any range between 49152 and 65536
//Teh Constructor
public Boolean Connect()
{
//SetInformation
Information.Id = 545;
using (var WebServ = new ClientSDKSoapClient("ClientSDKSoap"))
{
ContinueConnection.WaitOne();
WebServ.ClientLogin(Information);
}
return true;
}
~Connection()
{
using (var WebServ = new ClientSDKSoapClient("ClientSDKSoap"))
{
WebServ.ClientLogout(Information);
}
}
}
Additional Information
I want the web service to record if the Connection Class is destroyed for any given reason.
When the client is connecting, it works perfectly. The Web Service records every method called from it. If I call ClientLogout explicitly, it will work.
I am aware I can implement IDisposable; however, this object is not intended to be used within the lifetime of one method. In fact, its intended for use for the entire duration of the program and the failure of this object basically results in the failure of the entire project. (Although I suppose main IS a method...)
I need to release a network connection; however, its not in this program, its in another program and unless ClientLogout is called, it won't be released.
My Research
Microsoft says that you should use the deconstructor for the release of unmanaged resources making an explicit reference to network connections. This ones got my quite stumped.
I think you should implement a Dispose pattern for your Connection class, rather than relying on an obscure deconstructor metaphor. This would be the "canonical" way to do it.
public class Connection : IDisposable // <== Inherit from IDisposable interface
{
public const int Port = 50000;// Can be any range between 49152 and 65536
private SomeType webserv; // Use whatever real type is appropriate here.
private Information information = new Information(); // or whatever
// This is a real constructor.
public Connection()
{
//SetInformation
information.Id = 545;
webServ = new ClientSDKSoapClient("ClientSDKSoap"))
webserv.ContinueConnection.WaitOne();
webServ.ClientLogin(information);
}
// Implement IDisposable interface
public void Dispose()
{
webServ.ClientLogout(information);
}
}
And then use it thusly
using (var connection = new Connection())
{
// Use the connection here.
}
The client will be logged out when you leave the using block.
Microsoft says that you should use the deconstructor for the release of unmanaged resources making an explicit reference to network connections. This ones got my quite stumped.
The docs here are misleading. It really just means you need a finalizer somewhere in your object inheritance chain, to ensure that any unmanaged resources are appropriately cleaned up. But you only need this finalizer once for the entire inheritance tree, at the level where the unmanaged resource is first allocated.
As an example, you do not need a destructor or finalizer if you build a class for a data access layer to wrap the SqlConnection type, because the core SqlConnection type already has one. What you should do, though, is implement IDisposable and write code to ensure prompt disposal, so the finalizer on your SqlConnection will be called sooner, rather than later. But if you were to build a whole new database engine that competes with Sql Server, MySql, Oracle, Access, and the like, and were implementing the ADO.Net provider for this new database engine, then would need to write a finalizer for your connection type, because none exists yet.
In this case, ClientSDKSoap type already has a destructor; you do not need to write another.
What does System.ServiceModel.Clientbase.Open() do? I've never used it but just came across it in some code. Can it throw exceptions? If Close() is not called is it a problem?
If you create a proxy for a WCF service the proxy is effectively ClientBase
Example from my app:
public class DataClient : ClientBase<Classes.IDataService>, Classes.IDataService
{
public DataClient(string connectToHost)
: base(new NetTcpBinding(SecurityMode.Transport)
{
PortSharingEnabled = true,
Security = new NetTcpSecurity()
{
Transport = new TcpTransportSecurity()
{
ClientCredentialType = TcpClientCredentialType.Windows
}
}
},
new EndpointAddress(string.Format("net.tcp://{0}:5555/MyService",connectToHost)))
{ }
#region IDataService Members
public Classes.Folder GetFolder(string entryID)
{
return Channel.GetFolder(entryID);
}
public Classes.IItem GetItem(string entryID)
{
return Channel.GetItem(entryID);
}
#endregion
}
EDIT
Per your request I googled a bit and found this:
Implements ICommunicationObject.Open()
This led to this:
CommunicationException
The ICommunicationObject was unable to
be opened and has entered the Faulted
state.
TimeoutException
The default open timeout elapsed
before the ICommunicationObject was
able to enter the Opened state and has
entered the Faulted state.
Also, per experience and what I've come across on the 'net not closing your clients can cause various forms of strangeness to occur and is thus generally considered "A Bad Thing".
Just found this article:
Best Practice: Always open WCF client proxy explicitly when it is shared
https://blogs.msdn.microsoft.com/wenlong/2007/10/25/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared/
That states in the end:
If you don’t call the “Open” method first, the proxy would be opened internally when the first call is made on the proxy. This is called auto-open.
Why? When the first message is sent through the auto-opened proxy, it will cause the proxy to be opened automatically. You can use .NET Reflector to open the method System.ServiceModel.Channels.ServiceChannel.Call and see the following code:
if (!this.explicitlyOpened)
{
this.EnsureDisplayUI();
this.EnsureOpened(rpc.TimeoutHelper.RemainingTime());
}
When you drill down into EnsureOpened, you will see that it calls CallOnceManager.CallOnce. For non-first calls, you would hit SyncWait.Wait which waits for the first request to complete. This mechanism is to ensure that all requests wait for the proxy to be opened and it also ensures the correct execution order. Thus all requests are serialized into a single execution sequence until all requests are drained out from the queue. This is not a desired behavior in most cases.
To avoid such “serializing” artifact, the best practice is to open the proxy explicitly as above. Once you get to this point, you will be able to share the same proxy object among multiple threads.