I've been working with a piece of code, and started this thread: thread732-1539660. Now I'm having a problem adding an event with a custom set of arguments. The error I'm getting is An object reference is required for the non-static field, method, or property 'ConsoleClient.Program.de_OnExportFinished(DataExport.DataExporter, DataExport.DEEventArgs)'
Here's the code, with relevant (at least, what I think are relevant) lines in red. Can anyone enlighten me? TIA -Bob
Here's the code, with relevant (at least, what I think are relevant) lines in red. Can anyone enlighten me? TIA -Bob
Code:
[COLOR=red]//DataExporter.cs[/color]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using DataExport;
namespace DataExport
{
[COLOR=red]public delegate void DataExporterEvent (DataExporter sender, DEEventArgs deargs);[/color]
interface iDataMethods
{
void Export(string XMLFilePath);
int AddRecord(string RecordText);
bool AllowExport
{
get;
set;
}
[COLOR=red]event DataExporterEvent OnExportFinished;[/color]
}
[COLOR=red] public class DEEventArgs: EventArgs
{
private int es;
private string fname;
public DEEventArgs(int eStatus, string fName)
{
es = eStatus;
fname = fName;
}
public int ExportStatus
{
get { return es; }
}
public string FileName
{
get { return fname; }
}
}
[/color]
public class DataExporter : iDataMethods //implements the iDataMethods interface
{
private List<string> addedrecords = new List<string>(); //generic List object, will hold a single
//string field of data. In real life, this would either be an object, a struct, or perhaps a
//semicolon-delimited string that could be parsed into multiple fields.
private bool exportallowed;
private static DataExporter instance = null; //Holds a private reference to the singleton instance.
private static readonly object locker = new object(); //Used to lock a block of code
[COLOR=red]public event DataExporterEvent OnExportFinished;[/color]
private DataExporter() { } //overriding the default constructor to make it private. Private constructor
//requires instantiation via a method or property, in this case the Instance property.
public static DataExporter Instance //self-reference
{
get
{
lock (locker) //locking makes the code in the brackets execute atomically. This code is the basic
//singleton pattern: check for an existing instance, if not found create it, return result.
{
if (null == instance)
{
instance = new DataExporter(); //self-reference
}
return instance;
}
}
}
public bool AllowExport
{
get { return exportallowed; }
set { exportallowed = value; }
}
//Export transfers the present contents of the List object (addedrecords) into a DataSet (ds), writes
//the result to an XML file, and clears the List object.
public void Export(string XMLFilePath)
{
if (!exportallowed)
{
[COLOR=red]DEEventArgs deargs = new DEEventArgs(2, XMLFilePath);
if (OnExportFinished != null) { OnExportFinished(this, deargs); }[/color]
}
try
{
DataSet ds = new DataSet();
ds.Tables.Add();
ds.Tables[0].Columns.Add("TheField", typeof(string));
foreach (string ar in addedrecords)
{
ds.Tables[0].Rows.Add(ar);
}
ds.WriteXml(XMLFilePath);
addedrecords.Clear();
[COLOR=red]DEEventArgs deargs = new DEEventArgs(1, XMLFilePath);
if (OnExportFinished != null) { OnExportFinished(this, deargs); }[/color]
}
catch
{
[COLOR=red] DEEventArgs deargs = new DEEventArgs(0, XMLFilePath);
if (OnExportFinished != null) { OnExportFinished(this, deargs); }[/color]
}
}
public int AddRecord(string RecordText)
{
try
{
addedrecords.Add(RecordText);
return 1;
}
catch
{
return 0;
}
}
}
}
[COLOR=red]Program.cs[/color]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using DataExport;
namespace ConsoleClient
{
class Program
{
static void Main(string[] args)
//creating two threads that use the DataExporter singleton, to test for thread safety. The parameters
//"1" and "2" carry over into the XML files.
{
Thread t1 = new Thread(new ParameterizedThreadStart(doStuff));
Thread t2 = new Thread(new ParameterizedThreadStart(doStuff));
t1.Start("1");
t2.Start("2");
}
static void doStuff(Object tPar)
{
int eVal;
string fileName = "c:\\Temp\\myFile" + tPar + ".xml";
DataExporter de = DataExporter.Instance;
[COLOR=red] de.OnExportFinished+=new DataExporterEvent(de_OnExportFinished);
//*****ERROR HAPPENS HERE******[/color]
de.AllowExport = true;
lock (de) //Locking the block ensures thread safety. Removing the lock causes all of the line items
//in both threads to be written to each of the two xml files, when we want one thread for each file.
{
for (int i = 1; i <= 20; i++)
{
eVal = de.AddRecord("Thread " + tPar + "Record " + Convert.ToString(i));
if (0 == eVal)
{
Console.WriteLine("AddRecord didn't work");
return;
}
Thread.Sleep(100);
}
de.Export(fileName);
Console.WriteLine("strike a key when ready...");
Console.ReadKey(true);
}
}
[COLOR=red] private void de_OnExportFinished(DataExporter sender, DEEventArgs deargs)
{
switch (deargs.ExportStatus)
{
case 0:
Console.WriteLine("Export didn't work");
break;
case 2:
Console.WriteLine("Export function disabled");
break;
default:
Console.WriteLine("Export to " + deargs.FileName + " Successful.");
break;
}
}
[/color] }
}