J
John
Hi,
My app receives data via an async socket. I need to put this data into a
DataSet and display it via a DataGrid.
If I add the data to the dataset when it arrives using the async created
thread, my app crashes with a NullException inside Application.Run().
If I disconnect the DataSet from the DataGrid (dataGrid.DataSouce = null),
then the app does NOT crash. It only crashes when I'm trying to display the
data that I'm adding to the DataGrid.
So what's the best way to solve this problem? How do you get data into a
DataSet via the non-creating thread?
I built a demo app below that demonstrates the problem which is listed
below.
THANKS!
John
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
namespace DataGrid
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class DG : System.Windows.Forms.Form
{
Random random = new Random();
bool running = true;
private System.Windows.Forms.DataGrid dataGrid;
private DataGrid.MyDataset myDataset;
private System.Windows.Forms.Timer timer;
private System.Windows.Forms.CheckBox checkBox;
private System.ComponentModel.IContainer components;
public DG()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
dataGrid.DataSource = myDataset;
ThreadStart threadStart = new ThreadStart(listenThread);
Thread thread = new Thread(threadStart);
thread.IsBackground = true;
thread.Start();
}
private void listenThread()
{
while ( running )
{
// How do I add data to myDataset from this thread?
// If I add data to myDataset from this thread, while
// myDataset is "connected" to the datagrid, then the
// app will crash with a NullException
// How do I use the "main" thread to add data to myDataset?
// myDataset.MyTable.AddMyTableRow(DateTime.Now, random.Next());
Thread.Sleep(200);
}
}
/// <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.dataGrid = new System.Windows.Forms.DataGrid();
this.myDataset = new DataGrid.MyDataset();
this.timer = new System.Windows.Forms.Timer(this.components);
this.checkBox = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.dataGrid)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.myDataset)).BeginInit();
this.SuspendLayout();
//
// dataGrid
//
this.dataGrid.Anchor =
((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.To
p | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dataGrid.DataMember = "";
this.dataGrid.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.dataGrid.Location = new System.Drawing.Point(8, 48);
this.dataGrid.Name = "dataGrid";
this.dataGrid.Size = new System.Drawing.Size(280, 216);
this.dataGrid.TabIndex = 0;
//
// myDataset
//
this.myDataset.DataSetName = "MyDataset";
this.myDataset.Locale = new System.Globalization.CultureInfo("en-US");
//
// timer
//
this.timer.Tick += new System.EventHandler(this.timer_Tick);
//
// checkBox
//
this.checkBox.Location = new System.Drawing.Point(8, 8);
this.checkBox.Name = "checkBox";
this.checkBox.TabIndex = 1;
this.checkBox.Text = "Timer Enabled";
this.checkBox.CheckedChanged += new
System.EventHandler(this.checkBox_CheckedChanged);
//
// DG
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(296, 271);
this.Controls.Add(this.checkBox);
this.Controls.Add(this.dataGrid);
this.Name = "DG";
this.Text = "DataGrid Test";
((System.ComponentModel.ISupportInitialize)(this.dataGrid)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.myDataset)).EndInit();
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new DG());
}
private void checkBox_CheckedChanged(object sender, System.EventArgs e)
{
timer.Enabled = checkBox.Checked;
}
private void timer_Tick(object sender, System.EventArgs e)
{
// NOTE: THIS WORKS
// Console.WriteLine("Fire");
// myDataset.MyTable.AddMyTableRow(DateTime.Now, random.Next());
}
}
}
My app receives data via an async socket. I need to put this data into a
DataSet and display it via a DataGrid.
If I add the data to the dataset when it arrives using the async created
thread, my app crashes with a NullException inside Application.Run().
If I disconnect the DataSet from the DataGrid (dataGrid.DataSouce = null),
then the app does NOT crash. It only crashes when I'm trying to display the
data that I'm adding to the DataGrid.
So what's the best way to solve this problem? How do you get data into a
DataSet via the non-creating thread?
I built a demo app below that demonstrates the problem which is listed
below.
THANKS!
John
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
namespace DataGrid
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class DG : System.Windows.Forms.Form
{
Random random = new Random();
bool running = true;
private System.Windows.Forms.DataGrid dataGrid;
private DataGrid.MyDataset myDataset;
private System.Windows.Forms.Timer timer;
private System.Windows.Forms.CheckBox checkBox;
private System.ComponentModel.IContainer components;
public DG()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
dataGrid.DataSource = myDataset;
ThreadStart threadStart = new ThreadStart(listenThread);
Thread thread = new Thread(threadStart);
thread.IsBackground = true;
thread.Start();
}
private void listenThread()
{
while ( running )
{
// How do I add data to myDataset from this thread?
// If I add data to myDataset from this thread, while
// myDataset is "connected" to the datagrid, then the
// app will crash with a NullException
// How do I use the "main" thread to add data to myDataset?
// myDataset.MyTable.AddMyTableRow(DateTime.Now, random.Next());
Thread.Sleep(200);
}
}
/// <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.dataGrid = new System.Windows.Forms.DataGrid();
this.myDataset = new DataGrid.MyDataset();
this.timer = new System.Windows.Forms.Timer(this.components);
this.checkBox = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.dataGrid)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.myDataset)).BeginInit();
this.SuspendLayout();
//
// dataGrid
//
this.dataGrid.Anchor =
((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.To
p | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dataGrid.DataMember = "";
this.dataGrid.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.dataGrid.Location = new System.Drawing.Point(8, 48);
this.dataGrid.Name = "dataGrid";
this.dataGrid.Size = new System.Drawing.Size(280, 216);
this.dataGrid.TabIndex = 0;
//
// myDataset
//
this.myDataset.DataSetName = "MyDataset";
this.myDataset.Locale = new System.Globalization.CultureInfo("en-US");
//
// timer
//
this.timer.Tick += new System.EventHandler(this.timer_Tick);
//
// checkBox
//
this.checkBox.Location = new System.Drawing.Point(8, 8);
this.checkBox.Name = "checkBox";
this.checkBox.TabIndex = 1;
this.checkBox.Text = "Timer Enabled";
this.checkBox.CheckedChanged += new
System.EventHandler(this.checkBox_CheckedChanged);
//
// DG
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(296, 271);
this.Controls.Add(this.checkBox);
this.Controls.Add(this.dataGrid);
this.Name = "DG";
this.Text = "DataGrid Test";
((System.ComponentModel.ISupportInitialize)(this.dataGrid)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.myDataset)).EndInit();
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new DG());
}
private void checkBox_CheckedChanged(object sender, System.EventArgs e)
{
timer.Enabled = checkBox.Checked;
}
private void timer_Tick(object sender, System.EventArgs e)
{
// NOTE: THIS WORKS
// Console.WriteLine("Fire");
// myDataset.MyTable.AddMyTableRow(DateTime.Now, random.Next());
}
}
}