Re: Is 'connection pooling' obsolete given MARs?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Angel Saenz-Badillos[MS] (angelsa_at_online.microsoft.com)
Date: 02/07/04


Date: Sat, 7 Feb 2004 14:21:55 -0800


==Disclaimer, the information in this post is only relevant for the PDC
alpha of v2.0 Whidbey. Features may change considerably before the beta
ships.

This is going to be a tough area. The books/articles are correct, you can
definitely call EndXXX on the callbacks, that is what the callbacks are
there for. What you can't do is use an ado.net object (or any other non
thread safe object) in multiple threads. So, as long as you are not using
the command or connection object while you are waiting for the callback,
everything will work as expected. In pseudocode:

This will work:
con.Open()
command.BeginExecute(callback)
//do work here, do not use command or connection.*

//on a different thread
on_callback_called
command.EndExecute.

(*If you were not using the callback and where using the waitone/all you can
continue to use connection, create new command and execute on them with
mars)

If you where to use the command or connection while waiting for the callback
there is the possibility of running into multi-threaded issues. The worst
part is that you will get no exception and it will probably work perfectly
while you are testing the app. Then you will deploy and get the strangest
stress issues! I am looking for suggestions on what can be done to avoid
this.

This problem is going to be there for all non thread safe objects, not just
ado. The first thing I tried to do was do a BeginExecuteReader, fill a table
and bind this to a winform grid on the callback. Of course no go because the
table is non thread safe and I am touching it in both the main thread and
the callback. I thought the whole feature was broken until somebody showed
me this workaround:

  delegate void UICallback( object param );

  void ExecCallback( IAsyncResult ar )
  {
    using( SqlDataReader r=_cmd.EndExecuteReader( ar ) )
    {
     DataTable t=new DataTable();
     t.Load( r );
     this.Invoke( new UICallback( ReBindOnUIThread ), new object[] { t } );
    }
   }
  }

  void ReBindOnUIThread( object param )
  {
   if( param is DataTable )
   {
    dataGrid1.DataSource=param;
    _cmd=null;
   }

  }
ReBindOnUIThread executes in the main thread so we can bind to the dataGrid
and still be thread safe!

With this I think you have all the tools to solve your problem. Use a
different connection in each of your threads and don't use it while waiting
for the callback, use delegates to rebind to the main thread where
necessary.
Hope this helps,

-- 
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.
"Lecture Snoddddgrass" <maley@hamburg.fry> wrote in message
news:#p#LbWP7DHA.2480@TK2MSFTNGP12.phx.gbl...
>     Your comments on connection thread safety kind of bum me out, but at
> least now I understand why it has to be that way. Some of the
books/articles
> out there are suggesting that using the async callbacks [then calling
> EndExecuteNonQuery() on the thread pool thread] is an acceptable way to
> handle things. Well, you're still in the alpha stage so I guess I should
cut
> them some slack! :)
>
> > That's a tough scenario I will have to take a longer look at it. There
> > should be a way to get async to work for you here, but it is probably
not
> > going to be something off the shelf.
>
>     I'd like to hear more of your thoughts on this. This issue has been
> plaguing me for some time. You seem to know this ADO.NET stuff really well
> and I'd be thrilled to hear your suggestions.
>
> Thanks!
>
>


Relevant Pages

  • Re: Thread safety of asynchronous sockets, also - documentation vs reality
    ... worker thread for each client connection and then use synchronous ... think-type delay, and when your callback function was ... watches that port for input *without* creating an additional thread. ...
    (microsoft.public.dotnet.framework)
  • Event Machine - callbacks from different connections
    ... "You can also call send_data to write to a connection other than the one ... whose callback you are calling send_data from. ... I want a packet of data to be sent out on port 1700 when a packet ... puts "Port = #" ...
    (comp.lang.ruby)
  • Re: sockets : Writing and reading on the same thread with events ?
    ... but the BeginReceive method use another thread even when you don't specify a callback. ... then there is no performance optimization you can make that will matter when it comes to network i/o. ... The cost of the network i/o itself (i.e. the bandwidth of the actual network connection) is so much higher than that of any code that will handle moving the data into or out of that connection that optimizing the latter is pointless. ...
    (microsoft.public.dotnet.framework)
  • DDE Call back and its parameters and values
    ... (correct TCallBack to TFNCallBack - other changes can be done too) ... I have a connection and can get data and poke them too. ... When CallBack is 1, it is when data changes, when callback is 0 it is ...
    (comp.lang.pascal.delphi.misc)
  • Re: server scenario - variables in the right spot?
    ... If I'm correct in what I think you mean by 'data structures' then I also ... steps, the command has, and a way to mark which steps are done or not done, ... Assuming you are using the same receive callback for each BeginReceive, ... that processes the data for the first buffer. ...
    (microsoft.public.dotnet.languages.csharp)