ArrayList of objects serialization exception in c# - c#

I have an ArrayList which consist of lots of object created by me. I am trying to keep it. As far as I look, the best solution for that is to use binary formatter. But something is wrong with my code. It doesn't work either writing or reading. Here is my code;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private ArrayList allList = new ArrayList();
private FileStream fileStream;
private MemoryStream memoryStream;
public Form1()
{
InitializeComponent();
fileStream = new FileStream("pcdata.dat",FileMode.OpenOrCreate,FileAccess.ReadWrite);
memoryStream = new MemoryStream();
}
public void acceptDevice(Device receivedDevice)
{
//Somehow I call this method
allList.Add(receivedDevice);
saveDeviceDataToFileStream();
}
private void saveDeviceDataToFileStream()
{
SerializeToStream(allList).WriteTo(fileStream);
}
private void loadDeviceDataFromFileStream()
{
fileStream.CopyTo(memoryStream);
allList = (ArrayList)DeserializeFromStream(memoryStream);
}
public static MemoryStream SerializeToStream(object o)
{
MemoryStream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, o);
return stream;
}
public static object DeserializeFromStream(MemoryStream stream)
{
IFormatter formatter = new BinaryFormatter();
stream.Seek(0, SeekOrigin.Begin);
if (null == stream)
{
return null;
}
object o = formatter.Deserialize(stream);
return o;
}
}
}
This is my device class:
namespace WindowsFormsApplication1
{
[Serializable]
public class Device
{
public MyPanel panel; //panel class that I created
public String id;
public int deviceNumber;
public Device(String id, int deviceNumber)
{
panel = new MyPanel();
this.id = id;
this.deviceNumber = deviceNumber;
}
}
}
And this is myPanel class:
namespace WindowsFormsApplication1
{
public class MyPanel : TableLayoutPanel
{
public Panel panel1 = new Panel();
public Panel panel2 = new Panel();
public Panel panel3 = new Panel();
public Panel panel4 = new Panel();
public PictureBox pictureBox1 = new PictureBox();
public Label nameLabel = new Label();
public MyPanel()
{
//...
}
}
}
This is it. When I tried to tun it I get this exception :
SerializationException was unhandled
An unhandled exception of type
'System.Runtime.Serialization.SerializationException' occurred in
mscorlib.dll
Additional information: 'WindowsFormsApplication1, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' Derlemesindeki
'WindowsFormsApplication1.MyPanel' ...

I dont think you will be able to just serialize controls like that. I would suggest creating classes around the data you want to save and make the controls only responsible for display.
[Serializable]
public class MyPanelInfo
{
public PanelInfo panel1;
public PanelInfo panel2;
public PanelInfo panel3;
public PanelInfo panel4;
public Image image;
public string nameLabel;
public MyPanelInfo()
{
}
}
[Serializable]
public class PanelInfo
{
public string id;
public string name;
}

Related

this code give this exception "System.IO.IOException: 'The process cannot access the file because it is being used by another process.' "

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace FileManager
{
class FileManager : IDisposable
{
private readonly string filePath;
private readonly string copiedFilePath;
//private readonly Stream openFile;
private readonly StreamReader streamReader;
private readonly StreamWriter streamWriter;
private readonly StreamWriter streamCopy;
private readonly bool boolAppend = true;
public FileManager(string filePath, string destinationPath)
{
this.filePath = filePath;
this.copiedFilePath = destinationPath;
if (!File.Exists(filePath) || !File.Exists(destinationPath))
{
throw new Exception("file not found");
}
this.streamWriter = new StreamWriter(this.filePath,boolAppend);
this.streamReader = new StreamReader(this.filePath);
this.streamCopy = new StreamWriter(this.copiedFilePath, boolAppend);
}
public string ReadFromFile()
{
string content = streamReader.ReadToEnd();
return content;
}
public void WriteToFile(string content)
{
streamWriter.WriteLine(content);
}
public void Copy()
{
string copiedcontent = ReadFromFile();
streamCopy.WriteLine(copiedcontent);
}
public void Dispose()
{
streamCopy.Dispose();
streamReader.Dispose();
streamWriter.Dispose();
}
}
}
I'm trying to make an example on how to implement Idisposable interface to my FileManager calss.
is there any way to dispose streamCopy , streamReader and streamWriter in the dispose() method without getting this error?
thanks in advance for your help
.
Do you really get the exception during Dispose? I would guess the error is in the constructor. These two lines open the same file twice:
this.streamWriter = new StreamWriter(this.filePath,boolAppend);
this.streamReader = new StreamReader(this.filePath);
The second line probably causes the exception, because the file is already open.

protobuff-net save / load static fields

Is there anyway to save static fields or optimally a full static class in ProtoBuffNet. The person.bin size is 0 after saving, so I believe the issue is that it is not saving any static fields.
using ProtoBuf;
using System;
using System.IO;
using System.Windows.Forms;
namespace ProtoBuffNet
{
[ProtoContract(SkipConstructor = true)]
public class Person
{
[ProtoMember(1)]
public static int Id = -1;
[ProtoMember(2)]
public static string Name = "";
}
public partial class Form1 : Form
{
Person person = new Person();
public Form1()
{
InitializeComponent();
}
public static void setPerson()
{
Person.Id = 12345;
Person.Name = "Fred";
}
public static void resetPerson()
{
Person.Id = -1;
Person.Name = "";
}
private void button1_Click(object sender, EventArgs e)
{
setPerson();
using (var file = File.Create("person.bin"))
{
Serializer.Serialize(file, person);
}
// person Here:
// person.Id = 12345
// person.Name = "Fred"
}
private void button2_Click(object sender, EventArgs e)
{
resetPerson();
Person newPerson;
using (var file = File.OpenRead("person.bin"))
{
newPerson = Serializer.Deserialize<Person>(file);
}
// What happens:
// newPerson.Id = -1
// newPerson.Name = ""
// What I want:
// newPerson.Id = 12345
// newPerson.Name = "Fred"
}
}
}
The above code runs, but appears not to be saving the static fields. It would be optimal if Person class could be static as well.
Right now, the library is oriented around instances - usually objects. Frankly, most serialization tools are. You could fake it with a shim object that just proxies instance values to the static members, but... it isn't specifically a targeted scenario.

Trying to implement singleton gives me stackoverflow error c#

I am trying to make a singleton to account all the controllers I am going to create. When I run the website I get the stackoverflow error.
This is my singleton class:
public class MainController
{
private DatabaseController databaseController;
private UserDBController userDBController;
private static MainController MCinstance = null;
public MainController()
{
if (MCinstance == null)
{
databaseController = new DatabaseController();
userDBController = new UserDBController();
}
}
public static MainController Instance
{
get
{
if (MCinstance == null)
{
MCinstance = new MainController();
}
return MCinstance;
}
}
public UserDBController GetUserDBController()
{
return userDBController;
}
public DatabaseController GetDBController()
{
return databaseController;
}
}
This is how I use the singleton class in a different class:
private UserDBController userDBController = MainController.Instance.GetUserDBController();
What am I doing wrong?
You can change your implemention like below,
public class MainController
{
private DatabaseController databaseController;
private UserDBController userDBController;
private static MainController MCinstance = null;
static MainController()
{
MCinstance = new MainController();
MCinstance.databaseController = new DatabaseController();
MCinstance.userDBController = new UserDBController();
}
public static MainController Instance
{
get
{
return MCinstance;
}
}
public UserDBController GetUserDBController()
{
return userDBController;
}
public DatabaseController GetDBController()
{
return databaseController;
}
}
You should add the readonly modifier to your MCinstance declaration and instantiate it only once in static constructor.
public class MainController
{
public static readonly MainController Instance = null;
static MainController()
{
Instance = new MainController()
}
}
For singleton use need to use private constructor. And move code of private construct in the place where instance is creating.
public class MainController
{
private DatabaseController databaseController = new DatabaseController();
private UserDBController userDBController = new UserDBController();
private static MainController MCinstance = null;
private MainController()
{
}
public static MainController Instance
{
get
{
if (MCinstance == null)
{
MCinstance = new MainController();
}
return MCinstance;
}
}
public UserDBController GetUserDBController()
{
return userDBController;
}
public DatabaseController GetDBController()
{
return databaseController;
}
}
Essentially, this is the only code you need by making use of static classes in C#. The constructor is not public, since it is automatically called the first time you use this class. This class only has one instance.
public static class MainController
{
private static DatabaseController databaseController;
private static UserDBController userDBController;
static MainController()
{
databaseController = new DatabaseController();
userDBController = new UserDBController();
}
public static UserDBController GetUserDBController()
{
return userDBController;
}
public static DatabaseController GetDBController()
{
return databaseController;
}
}

Giving object in dll a click method from another project

is it possible to adding a click method to a class in dll from another project?
I want to create a class (Class1) in a class library and build a dll from it.
I will use that class in a project with references the dll.
This is my class (Class1)
public class Class1
{
public ImageMap map = null;
public Class1(Form f)
{
map = new ImageMap();
map.RegionClick += f.RegionMap_Clicked;
}
}
and this is my form (Form1) in another project.
public partial class Form1 : Form
{
Class1 c = null;
public Form1()
{
InitializeComponent();
c = new Class1(this);
}
void RegionMap_Clicked(int index, string key)
{
MessageBox.Show(key);
}
}
This is my first time asking here. So, sorry if my english is bad.
Class1 can be made independent from Form1:
public class Class1
{
public ImageMap Map = null;
public Class1()
{
this.Map = new ImageMap();
}
}
And Form1 uses Class1 however it likes:
public partial class Form1 : Form
{
private Class1 c = null;
public Form1()
{
InitializeComponent();
this.c = new Class1();
this.c.Map.RegionClick += this.RegionMap_Clicked;
}
private void RegionMap_Clicked(int index, string key)
{
MessageBox.Show(key);
}
}
Thus only the Form1 project needs a reference to the Class1 project.
Yes it's possible, don't forget to make your handler public:
public void RegionMap_Clicked(int index, string key)
{
MessageBox.Show(key);
}
You should do this
public class Class1
{
public ImageMap map = null;
public Class1(Form1 f)
{
map = new ImageMap();
map.RegionClick += f.RegionMap_Clicked;
}
}
then
public partial class Form1 : Form
{
Class1 c = null;
public Form1()
{
InitializeComponent();
c = new Class1(this);
}
public void RegionMap_Clicked(int index, string key)
{
MessageBox.Show(key);
}
}
and of couse you shold add using for this assembly.
I think now it will be working well

How can I redirect the stdout of IronPython in C#?

I have the following:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button3_Click(object sender, EventArgs e)
{
try
{
var strExpression = #"
import sys
sys.stdout=my.write
print 'ABC'
";
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
var sourceCode = engine.CreateScriptSourceFromString(strExpression);
scope.SetVariable("my", this);
var actual = sourceCode.Execute<string>(scope);
textBox1.Text += actual;
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public void write(string s)
{
textBox1.Text += s;
}
}
But I am getting an Exception that says there is no write.
What am I doing incorrectly?
You can set a stream and a textwriter directly from c#:
engine.Runtime.IO.SetOutput(stream, txtWriter);
engine.Runtime.IO.SetErrorOutput(stream, txtWriter);
To redirect the output for example you could override TextWriter class with a new one writing on your textbox.
e.g.
in my application I did an override of StreamWriter class that rises events when something is written on the stream (here just a part of the code):
public class MyEvtArgs<T> : EventArgs
{
public T Value
{
get;
private set;
}
public MyEvtArgs(T value)
{
this.Value = value;
}
}
public class EventRaisingStreamWriter : StreamWriter
{
#region Event
public event EventHandler<MyEvtArgs<string>> StringWritten;
#endregion
#region CTOR
public EventRaisingStreamWriter(Stream s):base(s)
{ }
#endregion
#region Private Methods
private void LaunchEvent(string txtWritten)
{
if (StringWritten != null)
{
StringWritten(this, new MyEvtArgs<string>(txtWritten));
}
}
#endregion
#region Overrides
public override void Write(string value)
{
base.Write(value);
LaunchEvent(value);
}
public override void Write(bool value)
{
base.Write(value);
LaunchEvent(value.ToString());
}
// here override all writing methods...
#endregion
}
Then in your application you should just do something like:
MemoryStream ms = new MemoryStream();
EventRaisingStreamWriter outputWr = new EventRaisingStreamWriter(ms);
outputWr.StringWritten += new EventHandler<MyEvtArgs<string>>(sWr_StringWritten);
var engine = Python.CreateEngine();
engine.Runtime.IO.SetOutput(ms, outputWr);
engine.CreateScriptSourceFromString("print 'hello world!'").Execute();
void sWr_StringWritten(object sender, MyEvtArgs<string> e)
{
textBox1.Text += e.Value;
}
Your example is close to working.
The problem you saw is because sys.stdout=my.write should be sys.stdout=my.
It also appears that Python expects to find a boolean softspace attribute.
I have made these two changes in the code below. Hopefully this should now work as you expected.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button3_Click(object sender, EventArgs e)
{
try
{
var strExpression = #"
import sys
sys.stdout=my
print 'ABC' ";
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
var sourceCode = engine.CreateScriptSourceFromString(strExpression);
scope.SetVariable("my", this);
var actual = sourceCode.Execute(scope);
textBox1.Text += actual;
} catch (System.Exception ex) {
MessageBox.Show(ex.ToString());
}
}
public bool softspace;
public void write(string s)
{
textBox1.Text += s;
}
}
This worked fine for me
pyRuntime = Python.CreateRuntime();
pyRuntime.IO.SetOutput(Console.OpenStandardOutput(), new UTF8Encoding(true, false));

Categories