Well, I've written a class that replicates the locks and the threads I am using in my application. Apologies its longer than before, but on the upside is all self contained.
I've removed the m_EndInvoke and AsyncCallBack as per your suggestion, but still the update method dosent get called after a several iterations. I've put in a second timer to simulate the work with the api.
Thanks so much in advance! This is prooving very helpful.
using System;
using System.Data;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Diagnostics;
using System.Timers;
using System.Threading;
using System.Runtime.CompilerServices;
namespace WindowsApplication5
{
public class Form1 : System.Windows.Forms.Form
{
private System.IAsyncResult m_EndInvoke = null;
private delegate void createCalclulations();
private delegate void doCalclulations();
private bool updatingForm = false;
private ArrayList tempCache = new ArrayList();
private DataTable trprod ;
private DataTable nets ;
private DataTable instruments ;
private DataSet ds;
private DataGrid positions;
private Traders traders;
private TraderProducts traderproducts;
private System.Timers.Timer cacheTimer;
private System.Timers.Timer cacheTimer2;
private Object testLock = new object();
private Object boolLock = new object();
private Object calcLock = new object();
private Object updateLock = new object();
private Object updateDataset = new Object();
private object[] allCurrentNets;
private object[] allTPs ;
private System.ComponentModel.Container components = null;
private int ccc = 0;
public Form1()
{
Thread.CurrentThread.Name = "mainUIThread";
Thread.CurrentThread.Priority = ThreadPriority.Highest;
traders = new Traders();
InitializeComponent();
traderproducts = new TraderProducts();
frmDrawComponents();
loadData();
allCurrentNets = new object[10 ];
allTPs = new object[10 ];
createTimer() ;
}
private void createTimer()
{
cacheTimer = new System.Timers.Timer();
cacheTimer.Elapsed += new ElapsedEventHandler(cacheTimer_Tick );
cacheTimer.Interval = 1000;
cacheTimer.Enabled = true;
cacheTimer2 = new System.Timers.Timer();
cacheTimer2.Elapsed += new ElapsedEventHandler(cacheTimer_Tick2 );
cacheTimer2.Interval = 1000;
cacheTimer2.Enabled = true;
}
public void cacheTimer_Tick(Object source, ElapsedEventArgs e )
{
Console.WriteLine("in timer");
lock(testLock)
{
Thread.CurrentThread.Priority = ThreadPriority.Lowest;
Console.WriteLine("in test lock");
if (!this.updatingForm)
{
Console.WriteLine("in updating form");
lock(this.boolLock)
{// need to lock this to update forn variable
Console.WriteLine("in bool lock");
this.updatingForm = true;
}
this.calculateNetFly();
// method should be called from a threadpool thread
//ThreadStart theadstart = new ThreadStart(this.calculateNetFly);
//m_EndInvoke = theadstart.BeginInvoke( new AsyncCallback(MethodBeginInvoke), null);
}
}
}
public void cacheTimer_Tick2(Object source, ElapsedEventArgs e )
{
lock(this.tempCache)
{
this.tempCache.Add(null);
Console.WriteLine("peek");
}
}
// private void MethodBeginInvoke (System.IAsyncResult ar )
// {
// Console.WriteLine("method begininvoke" + Thread.CurrentThread.Name);
// updateMainNets();
//
// }
public void calculateNetFly()
{
Console.WriteLine("Current thread name from constructor: " + Thread.CurrentThread.Name);
lock(calcLock) //locking an object flag - should ensure only one thread ever comes into this method at a time
{
lock(this.tempCache)
{
int size = this.tempCache.Count;
for (int a = 0; a < size; a++ )
{
this.tempCache.RemoveAt(a);
}
}
lock(allTPs)
{
Thread.Sleep(500);
}
lock(allCurrentNets)
{
Thread.Sleep(500);
}
//Thread.Sleep(500);
}
updateMainNets();
}
private void updateMainNets()
{
Console.WriteLine("update main nets: " + System.DateTime.Now);
if (Monitor.TryEnter(updateDataset,10))
{
if (this.InvokeRequired)
{
createCalclulations cc = new createCalclulations(this.updateMainNets);
Monitor.Exit(updateDataset);
this.Invoke(cc); //marshelled to main UI thread
return;
}
Console.WriteLine("in update lock");
int count = this.ds.Tables[1].Rows.Count;
lock(allTPs)
{
for (int k = 0 ; k < count ; k++ )
{
string product = (string)ds.Tables[1].Rows[k]["Product"];
string trader = (string)ds.Tables[1].Rows[k]["TraderId"];
string contract = (string)ds.Tables[1].Rows[k]["Contract"];
ds.Tables[1].Rows[k]["NetPosition"] = ccc;
ds.Tables[1].Rows[k]["NetPositionFly"]= ccc;
}
}
int count2 = this.ds.Tables[2].Rows.Count;
lock(allCurrentNets)
{
for (int k = 0 ; k < count2 ; k++ )
{
ds.Tables[2].Rows[k]["NightLimit"] = ccc;
ds.Tables[2].Rows[k]["DayLimit"]= ccc;
}
}
int count3 = this.ds.Tables[0].Rows.Count;
for (int k = 0 ; k < count3 ; k++ )
{
ds.Tables[0].Rows[k]["Limit"] = ccc;
}
Console.WriteLine(System.DateTime.Now + " " + ccc);
ccc++;
lock(boolLock)// need to lock this to update forn variable
{
this.updatingForm= false;
Console.WriteLine("this.updatingForm " + this.updatingForm);
}
Monitor.Exit(updateDataset);
}
Application.DoEvents();
}
public void loadData()
{
object[] t00 = {"aa", "L", "ok"};
this.traders.productTable.LoadDataRow(t00,true );
object[] t01 = {"bb", "L", "ok"};
this.traders.productTable.LoadDataRow(t01,true );
object[] t02 = {"cc", "L", "ok"};
this.traders.productTable.LoadDataRow(t02,true );
object[] t03 = {"dd", "L", "ok"};
this.traders.productTable.LoadDataRow(t03,true );
object[] t04 = {"ee", "L", "ok"};
this.traders.productTable.LoadDataRow(t04,true );
object[] row = {"aa", "L", "12",0,10,"ok",20,"ok" };
this.traderproducts.netData.LoadDataRow(row,true );
object[] row1 = {"bb", "L", "12",0,10,"ok",20,"ok" };
this.traderproducts.netData.LoadDataRow(row1,true );
object[] row2 = {"cc", "L", "12",0,10,"ok",20,"ok" };
this.traderproducts.netData.LoadDataRow(row2,true );
object[] row3 = {"dd", "L", "12",0,10,"ok",20,"ok" };
this.traderproducts.netData.LoadDataRow(row3,true );
object[] row4 = {"ee", "L", "12",0,10,"ok",20,"ok" };
this.traderproducts.netData.LoadDataRow(row4,true );
object[] row6 = {"aa", "L", "JUN", 0, 0};
this.traderproducts.data.LoadDataRow(row6,true );
object[] row7 = {"bb", "L", "JUN", 0, 0};
this.traderproducts.data.LoadDataRow(row7,true );
object[] row8 = {"cc", "L", "JUN", 0, 0};
this.traderproducts.data.LoadDataRow(row8,true );
object[] row9 = {"dd", "L", "JUN", 0, 0};
this.traderproducts.data.LoadDataRow(row9,true );
object[] row10 = {"ee", "L", "JUN", 0, 0};
this.traderproducts.data.LoadDataRow(row10,true );
}
public void frmDrawComponents()
{
this.ds = new DataSet();
trprod = this.traders.productTable;
nets = this.traderproducts.netData;
instruments = this.traderproducts.data;
this.ds.Tables.Add(trprod);
this.ds.Tables.Add(instruments);
this.ds.Tables.Add(nets);
DataColumn[] parentCols = new DataColumn[2] ;
parentCols[0] = this.ds.Tables[trprod.TableName].Columns["id"];
parentCols[1] = this.ds.Tables[trprod.TableName].Columns["Prod"];
DataColumn[] pCols = new DataColumn[2] ;
pCols[0] = this.ds.Tables[trprod.TableName].Columns["id"];
pCols[1] = this.ds.Tables[trprod.TableName].Columns["Prod"];
DataColumn[] childCols = new DataColumn[2] ;
childCols[0] = this.ds.Tables[nets.TableName].Columns["TraderId"];
childCols[1] = this.ds.Tables[nets.TableName].Columns["Product"];
DataColumn[] netChildCols = new DataColumn[2] ;
netChildCols[0] = this.ds.Tables[instruments.TableName].Columns["TraderId"];
netChildCols[1] = this.ds.Tables[instruments.TableName].Columns["Product"];
this.ds.Relations.Add("Net Positions", pCols , netChildCols);
this.ds.Relations.Add("Net Limits", parentCols , childCols);
this.positions= new System.Windows.Forms.DataGrid();
this.positions.SetDataBinding(this.ds,trprod.TableName);
this.positions.BackColor = Color.Silver;
this.positions.BackgroundColor = Color.Silver;
this.positions.AllowDrop = false;
this.positions.AlternatingBackColor = System.Drawing.Color.LightGray;
this.positions.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.positions.CaptionVisible = true;
this.positions.CaptionBackColor =Color.Silver;
this.positions.CaptionForeColor =Color.Red;
this.positions.FlatMode = true;
this.positions.Font = new System.Drawing.Font("Verdana", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.positions.GridLineColor = System.Drawing.SystemColors.HighlightText;
this.positions.GridLineStyle = System.Windows.Forms.DataGridLineStyle.None;
this.positions.HeaderForeColor = Color.Red;
this.positions.PreferredRowHeight = 25;
//this.positions.ReadOnly = true;
this.positions.RowHeadersVisible = false;
this.positions.HeaderBackColor = Color.Orange;
this.positions.AllowSorting = false;
this.positions.CausesValidation = false;
this.positions.Size = new System.Drawing.Size(390,300);
this.positions.Location = new System.Drawing.Point(10 , 40);
DataGridTableStyle trstyle = new DataGridTableStyle();
trstyle.HeaderBackColor = Color.Silver;
trstyle.MappingName = trprod.TableName;
DataGridColumnStyle trid = new DataGridTextBoxColumn ();
trid.MappingName = "id";
trid.HeaderText = "ID";
trid.Width = 40;
trstyle.GridColumnStyles.Add(trid);
DataGridColumnStyle tridp = new DataGridTextBoxColumn ();
tridp.MappingName = "Prod";
tridp.HeaderText = "Prod";
tridp.Width = 40;
trstyle.GridColumnStyles.Add(tridp);
DataGridColumnStyle tridpl = new DataGridTextBoxColumn ();
tridpl.MappingName = "Limit";
tridpl.HeaderText = "lim";
tridpl.Width = 40;
trstyle.GridColumnStyles.Add(tridpl);
this.positions.TableStyles.Add(trstyle);
DataGridTableStyle ts1 = new DataGridTableStyle();
ts1.HeaderBackColor = Color.Silver;
ts1.MappingName = instruments.TableName;
DataGridColumnStyle TextCol = new DataGridTextBoxColumn();
TextCol.MappingName = "Contract";
TextCol.HeaderText = "c";
TextCol.Width = 50;
ts1.GridColumnStyles.Add(TextCol);
DataGridColumnStyle TextCol2 = new DataGridTextBoxColumn();
TextCol2.MappingName = "NetPosition";
TextCol2.HeaderText = "Net";
TextCol2.Width = 40;
ts1.GridColumnStyles.Add(TextCol2);
DataGridColumnStyle TextCol3 = new DataGridTextBoxColumn();
TextCol2.MappingName = "NetPositionFly";
TextCol2.HeaderText = "Fly";
TextCol2.Width = 40;
ts1.GridColumnStyles.Add(TextCol3);
positions.TableStyles.Add(ts1);
DataGridTableStyle netts1 = new DataGridTableStyle();
netts1.HeaderBackColor = Color.Silver;
netts1.MappingName = nets.TableName;
DataGridColumnStyle TextCol7 = new DataGridTextBoxColumn();
TextCol7.MappingName = "Name";
TextCol7.HeaderText = "";
TextCol7.Width = 20;
netts1.GridColumnStyles.Add(TextCol7);
DataGridColumnStyle TextCol8 = new DataGridTextBoxColumn();
TextCol8.MappingName = "Net";
TextCol8.HeaderText = "Net";
TextCol8.Width = 40;
netts1.GridColumnStyles.Add(TextCol8);
DataGridColumnStyle TextCol9 = new DataGridTextBoxColumn ();
TextCol9.MappingName = "DayLimit";
TextCol9.HeaderText = "Day";
TextCol9.Width = 40;
netts1.GridColumnStyles.Add(TextCol9);
DataGridColumnStyle TextCol4 = new DataGridTextBoxColumn ();
TextCol4.MappingName = "DayFlag";
TextCol4.HeaderText = "Flag";
TextCol4.Width = 40;
netts1.GridColumnStyles.Add(TextCol4);
DataGridColumnStyle TextCol5 = new DataGridTextBoxColumn ();
TextCol5.MappingName = "NightLimit";
TextCol5.HeaderText = "Night";
TextCol5.Width = 40;
netts1.GridColumnStyles.Add(TextCol5);
DataGridColumnStyle TextCol6 = new DataGridTextBoxColumn ();
TextCol6.MappingName = "NightFlag";
TextCol6.HeaderText = "Flag";
TextCol6.Width = 40;
netts1.GridColumnStyles.Add(TextCol6);
this.positions.TableStyles.Add(netts1);
this.Controls.Add(positions);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new System.Drawing.Size(300,300);
this.Text = "Form1";
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
public class TraderProducts
{
public DataTable data;
public DataTable netData;
public TraderProducts()
{
data = new DataTable("TraderData");
DataColumn tid = new DataColumn("TraderId", typeof(string));
DataColumn prod = new DataColumn("Product", typeof(string));
DataColumn contract = new DataColumn("Contract", typeof(string));
DataColumn netPosition = new DataColumn("NetPosition", typeof(int));
DataColumn netPositionFly = new DataColumn("NetPositionFly", typeof(int)) ;
data.Columns.Add(tid);
data.Columns.Add(prod);
data.Columns.Add(contract);
data.Columns.Add(netPosition);
data.Columns.Add(netPositionFly);
netData = new DataTable("NetTraderData");
DataColumn name = new DataColumn("Name", typeof(string));
DataColumn net = new DataColumn("Net", typeof(double));
DataColumn dayLimit = new DataColumn("DayLimit", typeof(double));
DataColumn dayFlag = new DataColumn("DayFlag", typeof(string)) ;
DataColumn nightLimit = new DataColumn("NightLimit", typeof(double));
DataColumn nightFlag = new DataColumn("NightFlag", typeof(string));
DataColumn traderId = new DataColumn("TraderId", typeof(string));
DataColumn netprod = new DataColumn("Product", typeof(string));
netData.Columns.Add(traderId);
netData.Columns.Add(netprod);
netData.Columns.Add(name);
netData.Columns.Add(net);
netData.Columns.Add(dayLimit);
netData.Columns.Add(dayFlag);
netData.Columns.Add(nightLimit);
netData.Columns.Add(nightFlag);
}
}
public class Traders
{
public DataTable productTable;
private int count = 0;
public Traders()
{
productTable = new DataTable("TraderProductTable");
DataColumn idcol = new DataColumn("id", typeof(string));
DataColumn prod = new DataColumn("Prod", typeof(string));
DataColumn limit = new DataColumn("Limit", typeof(string));
productTable.Columns.Add(idcol);
productTable.Columns.Add(prod);
productTable.Columns.Add(limit);
}
}
}