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.
Related
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.
cn = new SqlConnection(
ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString());
cn.Open();
Where should this code go assuming I have content pages and master pages?
Should I put it in the master pages Page_Init? Will it then be fully accessible from every stage of execution on my content pages?
I'm used to classic ASP, so I would usually do it:
Declare variables
Open connection
process code
Close connection
Render HTML
But there are lots of stages of the page lifecycle in .net so I am wondering where it is best to place this code?
And does this connection need closing, or will garbage handling take care of it for me?
For me id create a DataAccess Layer so that I can remove the database connectivity in the codebehind files. My webapp will then reference the Dal and expose a public method that will allow Dal interaction from the front end
in terms of opening and closing Dal connections - wrap it in a using statement - that takes care of opening and closing the connection when required.
more information on this can be found here - http://davidhayden.com/blog/dave/archive/2005/01/13/773.aspx
I would go too for the Data Access Layer, but in order to answer your question more directly, here is how would I do this in ASP.NET, also handling transactions.
Override OnPreInit: initialize connection, open it and start new transaction
Override OnUnload: commit/rollback transaction, close connection
Override Dispose: dispose of both connection and transaction
I would also add a VoteRollback() method used to request a transaction rollback if something goes wrong. Page execution continues (you'll have to handle problems through your code) but when the page is unloaded the transaction is rolled back
I would recommend you create a seperate class library project that exposes classes that relate to your tables in your database. Then put a reference to that project and away you go. To simplify opening/closing connections, writing classes etc take a look at Subsonic which will map all your tables for you and then you can do something like this in your codebehind.
Product prod = Product.Find(3);
prod.Name = "iPhone";
prod.Save();
In .Net it depends on the structure you use. If you connect explicitly by manually using a SqlConnection object, you'll need to manage its connection directly. If you use a dataset tableadapter object or a DataContext object with LINQ (my personal recommendation), the connection is typically managed for you, but you'll want to enclose your object within a using block to make sure it is collected properly.
Our team's consideration of a "best practice" is to built a universal data manager that implements IDisposable in our common data class that handles the lazy-loading of any connection based objects to retrieve data. This way we can enforce the closing of any connections within the dispose events of that data manager to keep it clean.
Edit:
I always start with Guthrie.
http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx
101 LINQ Samples
http://krisvandermotten.wordpress.com/2006/11/30/creating-a-data-access-layer-with-linq-to-sql-part-2/
Below is a code sample of a piece of my standard BaseDataManager. I should probably have created an interface for it a long time ago, but the abstract bit seems to get my other team members to adopt it fairly well. I post this code as is with no warranty, but it works for me, and it keeps my connection pool nice and clean (and we do a LOT of data pulls for document information stored in a database). I cut out a bunch of our other base methods to keep it simple, and what's below is the portion that answers your question directly:
[Serializable()]
public abstract class BaseDataManager : IDisposable
{
private bool _disposedValue = false;
private SqlConnection _connectionObject = null;
public BaseDataManager()
{
}
public BaseDataManager(string connectionString)
{
this.SqlConnectionString = connectionString;
}
public BaseDataManager(string connectionString, string username, string password)
{
if (!connectionString.EndsWith(";")) connectionString += ";";
this.SqlConnectionString += "User ID=" + username + ";password=" + password;
}
public string SqlConnectionString
{
get;
set;
}
public virtual SqlConnection Connection
{
get
{
if (_connectionObject == null && !String.IsNullOrEmpty(this.SqlConnectionString))
_connectionObject = new SqlConnection(this.SqlConnectionString);
return _connectionObject;
}
set
{
_connectionObject = value;
}
}
#region IDisposable Support
/// <summary>
/// (Protected) Method that performs actual cleanup on dispose. This interface
/// has been implemented to clean up data connections that are left stranded
/// when the class is disposed while the connection possibly remains open in
/// the connection pool. This opportunity is also used to free up the private
/// variables of the class.
/// </summary>
/// <param name="disposing">Used for explicitly calling Dispose</param>
protected virtual void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
//---------------------------------------------------------------------------------------------
// Close the connection object prior to setting it to nothing
//---------------------------------------------------------------------------------------------
if (_connectionObject != null) _connectionObject.Close();
_connectionObject = null;
}
_disposedValue = true;
}
}
/// <summary>
/// (Public) Method that implements IDisposable. This code is autogenerated
/// the implementation interface in the VS IDE. Do not change this code.
/// </summary>
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
You should only be using it when you need data from your database.
If you are not creating a DAL layer, then you would put this is your events such as page_load, or onClick events. You should not be opening a connection just for the sake of opening a connection on the page.
snippet of code for opening up connection
SqlConnection conn = null
try
{
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString);
conn.Open()
// do something with the connection
}
catch(Exception ex)
{
//log error
}
finally
{
// clean up connection
if(conn!=null)
{
//check if connetion is open, if it is close it / dispose
}
}
First thumb of rule, decouple the Domain layer from the ASP.NET specifics/View.
A lot of people create a class library for the Domain layer, that way it is guaranteed that the Page/View related code does not get blended with it.
So you would have a domain layer, where you have classes such as User, Comment, etc... and those classes would talk to the database. I usually have a DbUser class where all the database interaction happens, and DbUser inherits DbQuery which creates the connection for you. That way I can keep database interaction code completely to the Db{ClassName} class and DbQuery. It can really help if you want to keep the code really organized.
Simple scenario:
When I get a page request to view a profile of a specific user, I simply do User.GetUser(id); where id is the user id of the user. The User class has a static method GetUser, which creates a new instance of DbUser and calls the getUser method there. getUser method within the DbUser creates a connection and a query to the database, then it returns an instance of User and voila, you get it in your hands.
I hope my answer helps you in the right direction though it may be a bit off topic.
UPDATE: By decoupling the Domain layer from the website then you have more options, such as re-using the class library for another project that interacts to the same database.
I am using single-call server activated objects in .net remoting, and have a question about how to initialise the remoted objects.
When my server calls RemotingConfiguration.RegisterWellKnownServiceType() it passes a reference to the Type of the object to be instantiated to service client requests. How do I initialise these 'remote objects' after thay have been created and before the client uses them?
In my case, the remote objects need to connect to a database, so they need a connection string. How should they acquire this when the containing server doesn't known when they are created, and the remote object has no references to the containing server? What am I missing here?
(My workaround for the moment is to store the connection string in a static field, since all remote objects currently use the same database. This isn't very flexible though, and looks like a hack to me.)
I don't think there is an easy and clean way to just create the object. The object gets created when a remoting call comes in.
I don't think there is a need for that either though. You can create another class that handles all the initialization (it gets the connection string from wherever it wants, etc.) and then you can pull the connection string from the remoting object. You would create that object(s) on process start yourself.
Otherwise, you can put some logic in the constructor of the object. It can maybe read the connection string from a config file or whatever you like. You can also lazy load the variables decalred in that object (i.e. if connectionString = null, then GetConnectionString();) There are plenty of options really.
Please keep in mind I would not suggest doing initialization work in a SingleCall SAO as this work has to be done on every call to the SAO.
To manage connection strings I use a connection manager class.
Please consider the following code pseudo code as I just wrote it out to illustrate an idea. I've used this pattern for various systems I've written.
public enum DBConnection
{
DBTest1,
DBTest2
}
public static class ConnectionStringManager
{
static Exception _construtorException = null;
static Dictionary _connectionMap = new Dictionary();
static ConnectionStringManager()
{
try
{
// Load the _connectionMap
// You can use a custom application configuration section or
// connection strings defined as described in the following article
// http://msdn.microsoft.com/en-us/library/bf7sd233.aspx
}
catch(Exception ex)
{
// Any exception thrown in a static constructor needs to be kept track of because static
// constructors are called during type initialization and exceptions thrown
// are not caught by normal application exception handling.
// (At least as of .NET 2.0)
_constructorException = ex;
}
}
public static string GetConnectionString(DBConnection conn)
{
if ( _constructorEx != null )
throw new Exception("Error initializing ConnectionStringManager", _constructorException);
if ( !_connectionMap.ContainsKey(conn) )
throw new Exception(string.Format("Connection {0} not found", Enum.GetName(typeof(DBconnection), (int)conn));
return _connectionMap[conn];
}
}
You database code will use the connection manager class to retrieve connection strings.
Keep in mind that .NET remoting has been replaced by WCF, but some of us still have remoting in our legacy code :-)
I hope this helps!