473,320 Members | 1,846 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Asynchronous Design Pattern Using ThreadPool

Hi All,

I've been using the original (non-event based) asynchronous design
pattern using delegates. It works fine but performance wise I know
using the ThreadPool is supposed to be far better, so I wondered if
anyone had any examples of the best way to do this.

I've obviously had a look myself but haven't gotten very far and
although I've implemented a version myself I'm not sure its the best
that can be done.

Thanks,

Colin

Mar 29 '06 #1
1 2005
The way I usually approach this is to create a cached WaitCallBack in
the class, rather than having to create a new one each time I call
ThreadPool.QueueUserWorkItem.

Here's an example of a generic class that I've used before.

It's all based around a data-entry grid (the type is
PortfolioGridControl). It was used in an application that needed to
fire (and forget) events in other grids when the user entered a value
or moved the selected record.

GridCallBackEvent.cs.
The constructor takes a PortfolioGridControl object (used to correctly
fire via Invoke/InvokeRequired) and the delegate to fire (a GridEvent).

It then creates the WaitCallBack passing the address of an internal
function to call (InternalCalledBackEvent) which in turn calls
InvokeGridEvent to correctly invoke the define GridEvent delegate.

A public function, InvokeEvent, is used to fire the required event
passing EventArgs (GridControlEventArgs).

You'll need to remove the reference to PortfolioGridControl if you
don't plan to communicate with controls and just fire gridEvent
directly:

using System;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.CompilerServices;

namespace JHalesCallBacks
{

public class GridCallBackEvent
{

public delegate void GridEvent(GridControlEventArgs e);

private readonly GridEvent gridEvent;
private readonly PortfolioGridControl portfolioGridControl;
private readonly WaitCallback calledbackFromThreadPool;

public
GridCallBackEvent(PortfolioGridControl portfolioGridControl, GridEvent
gridEvent)
{
this.portfolioGridControl = portfolioGridControl;
this.gridEvent = gridEvent;

// create the pointer to our own method (CalledBackEvent) that will
be called back via threadpool
this.calledbackFromThreadPool = new
WaitCallback(InternalCalledBackEvent);
}

public void InvokeEvent(GridControlEventArgs e)
{
// Simple ask the
ThreadPool to fire our WaitCallBack
ThreadPool.QueueUserWorkItem(calledbackFromThreadP ool, e);
}
private void InternalCalledBackEvent(object state)
{
InvokeGridEvent(state as GridControlEventArgs);
}
/// This whole method is locked (using MethodImpl) as we don't want
race conditions
/// </summary>
[MethodImpl(MethodImplOptions.Synchronized)]
private void InvokeGridEvent(GridControlEventArgs e)
{
if (portfolioGridControl.InvokeRequired)
{
portfolioGridControl.Invoke(gridEvent, new object[] {e});
}
else
{
gridEvent(e);
}
}
}
}

GridControlEventArgs.cs is defined like this, and in my case it passes
along some useful arguments:

using System;

namespace JHalesCallBacks
{
public class GridControlEventArgs : EventArgs
{

public GridControlEventArgs(int aggrID, int assetID)
{
this.aggrID = aggrID;
this.assetID = assetID;
}

private int aggrID = 0;
public int AggrID
{
get { return aggrID;}
}

private int assetID = 0;
public int AssetID
{
get { return assetID;}
}

}
}

PortfolioGridControl.cs
Finally, in a User Control (PortfolioGridControl) that made use of the
GridCallBackEvent, I declared a class level instance that allows the
events to fire:

public class PortfolioGridControl : System.Windows.Forms.UserControl
{

private readonly GridCallBackEvent highlightPortfolioCallback;

public PortfolioGridControl()
{

// GridCallBackEvent wraps up all knowledge of getting a method
executed via threadpool
highlightPortfolioCallback = new GridCallBackEvent(this, new
GridCallBackEvent.GridEvent(HighlightEvent));
// add to centralised multicast handler
GridController.HighlightPortfolio += new
HighlightPortfolioHandler(highlightPortfolioCallba ck.InvokeEvent);
}

private void HighlightEvent(GridControlEventArgs e)
{
// This is the event that finally gets
called!
}
}

You can then eventually call highlightPortfolioCallback.InvokeEvent(new
GridControlEventArgs(aggrId, assetId)) to get HighlightEvent fired.

In my case, you can see that I added the definition for
highlightPortfolioCallback to a centralised multicast delegate in a
class called GridController which could fire groups of these events:
GridController.cs
using System;

namespace JHalesCallBacks
{
public class GridController
{

public static void FireHighlightPortfolio( int aggrId, int assetId)
{
if (HighlightPortfolio != null)
{
HighlightPortfolio(new GridControlEventArgs(aggrId, assetId));
}
}
public static event HighlightPortfolioHandler HighlightPortfolio;
}
}

Then it's just a case of calling
GridController.FireHighlightPortfolio() passing in the two args that it
requires

Hope that's not too convoluted!

Jason

Mar 30 '06 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Matthew Groch | last post by:
Hi all, I've got a server that handles a relatively high number of concurrent transactions (on the magnitude of 1000's per second). Client applications establish socket connections with the...
6
by: Quiet Man | last post by:
Hi all, I'm designing a fairly simple service that will run on W2K/SP4 and W2K3 servers. It's job is to be a very specialized database server that listens on a given IP address / TCP port and...
1
by: Julian Hershel | last post by:
Reading about asynchronous programming (ms-help://MS.NETFrameworkSDK/cpguidenf/html/cpconasynchronousdesignpatterno verview.htm) I could not clarify some doubts. Hope you can help me. 1) Are...
4
by: taskswap | last post by:
I have a legacy application written in C that I'm trying to convert to C#. It processes a very large amount of data from many clients (actually, upstream servers - this is a mux) simultaneously. ...
1
by: MSDN | last post by:
Does anyone know how to do this with a readline statement or equivalent method? Thanks in advance. Chris
3
by: Morgan Cheng | last post by:
Asynchronous I/O is said to be using native completion port. However, i checked rotor2.0 code, it seems not in stream.cs. BeginRead is defined in below way. In my understanding, If BeginInvoke is...
0
by: marian.kovac | last post by:
Hi, I have this simple sample code: class SearchRange { static int m = 0; static void Main(string args) { Discover discover = new Discover(); // Add discovered device handler
3
by: =?Utf-8?B?Sm9obg==?= | last post by:
Hi, I need to write asynchronous HTTPModule which will sometimes execute long job. I've written it using AddOnBeginRequestAsync but it still executes synchronously - I am checking performance...
0
by: APA | last post by:
I've seen the MS sample async web request pattern and I ask is it really async if it is using a ManualResetEvent and setting WaitOne()? The ManualResetEvent object is being declared as a static...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.