Hallo Leute,
da ich ja wieder weiter Arbeite an meinem Projekt "Katastrophale Haussteuerung die irgendwie funktionieren wird... mit viel glück" bin ich wieder auf ein Problem gestoßen. Mein Plan ist es die Methode homeputer_ChangedObjects jede zweite Sekunden ausführen zu lassen, um dann, wenn ich irgendwann so weit bin, die Values in einer Datenbank zu aktualisieren. Da dies aber natürlich nicht auf dem Main Thread laufen soll, habe ich mit einem Worker angefangen. Dieser startet sofort nachdem homeputer_InitDLL ausgeführt wurde. Doch das einzige was ich im Moment hin bekommen ist, das bei homeputer_ChangedObjects eine Exception ausgeführt wird. Dieses Exception wird hierbei ausgelöst:
#EDIT: Der ExternalException.ErrorCode lautet übrigens -2147467259
Ich denke es hat was damit zu tuen, das die DoWork Methode natürlich nicht auf dem MainThread ausgeführt wird, aber homeputer_InitDLL schon. Nur Multi Threading habe ich noch nie wirklich gemacht (So wie vieles halt xD).
Und MethodInvoker geht denke ich nur bei einer WindowsForms, wie ich es bei meiner LogInvoke Methode getan habe.
Hier aber erstmal mein Code:
Ich habe versucht meinen Code mit Kommentaren zu erklären, zwar nicht alles, doch genug damit man das eigentliche versteht. Wenn ich noch weitere Daten der Exception posten soll, dann sagt mir bescheid.
Ich denke ich bin einfach noch nicht fit genug im Thema Threads, und deshalb entsteht der Fehler.
MFG Nils
#EDIT: Ich bin etwas weiter gekommen. Ich habe es dann doch irgendwie mit MethodInvoke versucht. Also das Programm läuft gerade die ganze Zeit ohne Fehler. Sauber ist es nicht was ich da gemacht habe. Ich musste dann doch den Code von @jvbsl intigrieren, da anscheint dann wirklich ein Memory Fehler entsteht. Ich habe jetzt mit tausend try catch Blöcken gearbeitet.
Das Resultat meiner bisherigen Arbeit:
Homeputer.cs
Spoiler anzeigen
MainForm.cs
Spoiler anzeigen
Am besten wären paar Empfehlungen wie ich dies verbessern kann. Wie gesagt eigentlich habe ich die Sch***e nur mit mehr Sch***e verstärkt :D.
da ich ja wieder weiter Arbeite an meinem Projekt "Katastrophale Haussteuerung die irgendwie funktionieren wird... mit viel glück" bin ich wieder auf ein Problem gestoßen. Mein Plan ist es die Methode homeputer_ChangedObjects jede zweite Sekunden ausführen zu lassen, um dann, wenn ich irgendwann so weit bin, die Values in einer Datenbank zu aktualisieren. Da dies aber natürlich nicht auf dem Main Thread laufen soll, habe ich mit einem Worker angefangen. Dieser startet sofort nachdem homeputer_InitDLL ausgeführt wurde. Doch das einzige was ich im Moment hin bekommen ist, das bei homeputer_ChangedObjects eine Exception ausgeführt wird. Dieses Exception wird hierbei ausgelöst:
#EDIT: Der ExternalException.ErrorCode lautet übrigens -2147467259
Ich denke es hat was damit zu tuen, das die DoWork Methode natürlich nicht auf dem MainThread ausgeführt wird, aber homeputer_InitDLL schon. Nur Multi Threading habe ich noch nie wirklich gemacht (So wie vieles halt xD).
Und MethodInvoker geht denke ich nur bei einer WindowsForms, wie ich es bei meiner LogInvoke Methode getan habe.
Hier aber erstmal mein Code:
C#-Quellcode
- //Die Methoden der DLL
- [DllImport("homeputer.dll")]
- private static extern int homeputer_InitDLL();
- [DllImport("homeputer.dll")]
- private static extern int homeputer_ChangedObjects(StringBuilder s);
- [DllImport("homeputer.dll")]
- private static extern int homeputer_SetObjValName(String Objektname, String Objektwert);
- [DllImport("homeputer.dll")]
- private static extern int homeputer_ChangeCount();
- [DllImport("homeputer.dll")]
- private static extern int homeputer_SetWindowHandle(IntPtr Handl);
- [DllImport("homeputer.dll")]
- private static extern int homeputer_GetObjIdx(int Index, String Objektname, String Objektwert);
- [DllImport("homeputer.dll")]
- private static extern int homeputer_GetObjValName(String Objektname, String Objektwert);
- [DllImport("kernel32", SetLastError = true)]
- static extern IntPtr LoadLibrary(string lpFileName);
- static bool CheckLibrary(string fileName)
- {
- return LoadLibrary(fileName) == IntPtr.Zero;
- }
- public static MainForm mf;
- public static RefreshWorker rw;
- public static Thread rfwt;
- public static bool init()
- {
- try
- {
- int i = homeputer_InitDLL(); //Wichtig, das die DLL funktioniert.
- if (i == 1)
- {
- rw = new RefreshWorker();
- rw.mff = mf;
- rfwt = new Thread(rw.DoWork);
- rfwt.Start();
- }
- if (i == 1) return true;
- return false;
- }
- catch (System.DllNotFoundException)
- {
- mf.log("Can not find homeputer.dll");
- }
- return false;
- }
- public static void p() //Normale Methode, wenn ich auf einen Button in der Forms klicke, diese Funktioniert einwandfrei.
- {
- StringBuilder s = new StringBuilder(); //I am so sorry jvbsl, ich habe deine Methode noch nicht eingefügt :D
- try
- {
- homeputer_ChangedObjects(s);
- }
- catch (Exception ee) //Damit, wenn ein Fehler kommt sich das Programm nicht gleich beendet.
- {
- mf.logInvoke("Ex P: " + ee.StackTrace);
- }
- string sst = s.ToString();
- string[] sstt = sst.Split(';');
- for (int i = 0; i < sstt.Count() - 1; i++)
- {
- mf.log(i + ": " + sstt[i]);
- }
- }
- public static void stopRefreshWorker()
- {
- //Damit der Thread nach dem beenden nicht weiter läuft. Hatte damit schon große Probleme, weil ich die Datei nicht mehr ersetzen konnte und den Prozess nicht finden konnte. Deshalb wird er hier safe beendet.
- rw?.RequestStop();
- rfwt?.Join();
- }
- public class RefreshWorker
- {
- public void DoWork()
- {
- //homeputer_InitDLL();
- while (!_shouldStop)
- {
- mff.logInvoke("Run Thread"); //mff.logInvoke schreibt einfach die Log Daten in eine ListBox in der MainForm
- StringBuilder s = new StringBuilder();
- try
- {
- homeputer_ChangedObjects(s); //Hier entsteht die Exception.
- }
- catch (Exception ee)
- {
- //mff.logInvoke("Ex: " + ee.Data);
- mff.log("==> " + ee.ToString());
- RequestStop();
- }
- string sst = s.ToString();
- string[] sstt = sst.Split(';');
- for (int i = 0; i < sstt.Count() - 1; i++)
- {
- mff.logInvoke(i + ": " + sstt[i]);
- }
- Thread.Sleep(2000);
- }
- }
- public void RequestStop()
- {
- _shouldStop = true;
- }
- private volatile bool _shouldStop;
- public MainForm mff; //Um auf die MainForm zu greifen zu können.
- }
Ich habe versucht meinen Code mit Kommentaren zu erklären, zwar nicht alles, doch genug damit man das eigentliche versteht. Wenn ich noch weitere Daten der Exception posten soll, dann sagt mir bescheid.
Ich denke ich bin einfach noch nicht fit genug im Thema Threads, und deshalb entsteht der Fehler.
MFG Nils
#EDIT: Ich bin etwas weiter gekommen. Ich habe es dann doch irgendwie mit MethodInvoke versucht. Also das Programm läuft gerade die ganze Zeit ohne Fehler. Sauber ist es nicht was ich da gemacht habe. Ich musste dann doch den Code von @jvbsl intigrieren, da anscheint dann wirklich ein Memory Fehler entsteht. Ich habe jetzt mit tausend try catch Blöcken gearbeitet.
Das Resultat meiner bisherigen Arbeit:
Homeputer.cs
C#-Quellcode
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace Socket_Homeputer
- {
- class Homeputer
- {
- [DllImport("homeputer.dll")]
- private static extern int homeputer_InitDLL();
- [DllImport("homeputer.dll")]
- private static extern int homeputer_ChangedObjects(StringBuilder s);
- [DllImport("homeputer.dll")]
- private static extern int homeputer_SetObjValName(StringBuilder Objektname, StringBuilder Objektwert);
- [DllImport("homeputer.dll")]
- private static extern int homeputer_ChangeCount();
- [DllImport("homeputer.dll")]
- private static extern int homeputer_SetWindowHandle(IntPtr Handl);
- [DllImport("homeputer.dll")]
- private static extern int homeputer_GetObjIdx(int Index, String Objektname, String Objektwert);
- [DllImport("homeputer.dll")]
- private static extern int homeputer_GetObjValName(String Objektname, String Objektwert);
- [DllImport("kernel32", SetLastError = true)]
- static extern IntPtr LoadLibrary(string lpFileName);
- static bool CheckLibrary(string fileName)
- {
- return LoadLibrary(fileName) == IntPtr.Zero;
- }
- public static MainForm mf;
- public static RefreshWorker rw;
- public static Thread rfwt;
- public static int trys = 0;
- public static bool init()
- {
- try
- {
- int i = initDLL();
- Thread.Sleep(500);
- StringBuilder objname = new StringBuilder();
- objname.Append("Licht_SZDecke");
- StringBuilder objwert = new StringBuilder();
- objwert.Append("an");
- mf.log(homeputer_SetObjValName(objname, objwert).ToString());
- if (i == 1)
- {
- rw = new RefreshWorker();
- rw.mff = mf;
- rfwt = new Thread(rw.DoWork);
- rfwt.Start();
- }
- if (i == 1) return true;
- return false;
- }
- catch (System.DllNotFoundException)
- {
- mf.log("Can not find homeputer.dll");
- }
- return false;
- }
- public static int initDLL()
- {
- trys++;
- int i = homeputer_InitDLL();
- if (i == 0 && trys < 4)
- {
- return initDLL();
- } else
- {
- return i;
- }
- }
- public static void p()
- {
- try
- {
- homeputer_InitDLL();
- try
- {
- int size = homeputer_ChangeCount() * 32;
- StringBuilder s = new StringBuilder(size);
- try
- {
- homeputer_ChangedObjects(s);
- string sst = s.ToString();
- string[] sstt = sst.Split(';');
- for (int i = 0; i < sstt.Count() - 1; i++)
- {
- mf.log(i + ": " + sstt[i]);
- }
- }
- catch (Exception ee)
- {
- mf.log("Ex P: " + ee.ToString() + " | " + ee.HResult);
- }
- } catch (Exception ee)
- {
- mf.log(ee.ToString());
- }
- } catch (Exception ee)
- {
- mf.log(ee.ToString());
- }
- }
- public static void stopRefreshWorker()
- {
- rw?.RequestStop();
- rfwt?.Join();
- }
- public class RefreshWorker
- {
- public void DoWork()
- {
- //homeputer_InitDLL();
- //Thread.Sleep(1000);
- while (!_shouldStop)
- {
- try
- {
- /*
- mff.logInvoke("Run Thread");
- StringBuilder s = new StringBuilder();
- homeputer_ChangedObjects(s);
- string sst = s.ToString();
- string[] sstt = sst.Split(';');
- for (int i = 0; i < sstt.Count() - 1; i++)
- {
- mff.logInvoke(i + ": " + sstt[i]);
- }*/
- //homeputer_InitDLL();
- mff.tryP();
- }
- catch (Exception ee)
- {
- //mff.logInvoke("Ex: " + ee.Data);
- mff.logInvoke("==> " + ee.ToString());
- //RequestStop();
- //Thread.CurrentThread.Join();
- }
- Thread.Sleep(2000);
- }
- }
- public void RequestStop()
- {
- _shouldStop = true;
- }
- private volatile bool _shouldStop;
- public MainForm mff;
- }
- }
- }
MainForm.cs
C#-Quellcode
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using System.Security.Cryptography.X509Certificates;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using System.Windows.Forms.VisualStyles;
- using MaterialSkin;
- using MaterialSkin.Controls;
- namespace Socket_Homeputer
- {
- public partial class MainForm : MaterialForm
- {
- public MainForm()
- {
- InitializeComponent();
- Homeputer.mf = this;
- var materialSkinManager = MaterialSkinManager.Instance;
- materialSkinManager.AddFormToManage(this);
- materialSkinManager.Theme = MaterialSkinManager.Themes.LIGHT;
- materialSkinManager.ColorScheme = new ColorScheme(Primary.BlueGrey800, Primary.BlueGrey900, Primary.BlueGrey500, Accent.LightBlue200, TextShade.WHITE);
- logBox.Items.Add("[" + DateTime.Now.ToString() + "] Windows Form initialized.");
- bool init = Homeputer.init();
- log(init ? "Homeputer.dll was initialized." : "Homeputer.dll was not initialized.");
- if (!init) getChObj.Enabled = false;
- }
- public void log(String m)
- {
- logBox.Items.Add("[" + DateTime.Now.ToString() + "] " + m);
- }
- public void logInvoke(String m)
- {
- MethodInvoker mi = delegate {
- logBox.Items.Add("[" + DateTime.Now.ToString() + "] " + m);
- };
- if (InvokeRequired)
- this.Invoke(mi);
- }
- public void tryP()
- {
- Homeputer.p();
- }
- private void getChObj_Click(object sender, EventArgs e)
- {
- Homeputer.p();
- }
- }
- }
Am besten wären paar Empfehlungen wie ich dies verbessern kann. Wie gesagt eigentlich habe ich die Sch***e nur mit mehr Sch***e verstärkt :D.
Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Noim“ ()