Autor Beitrag
Leitstelle_V
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Di 31.03.20 21:49 
Hallo Th69,

vielen Dank für deine Hilfe :-). Also, vorab zu der Schleife, sehr gut, danke. Ich hatte mich schon mit Schleifen etc. beschäftigt und deinen Code fast genau so schon mal probiert gehabt. Aber halt nur fast. Ich hatte das [i] in der Zeile listBox1.Items.Add(filesOrFolders[i] + " " + DateTime.Now); vergessen... Da war das Ergebnis natürlich nicht wie gewünscht... Aber das lag an meiner mangelnden Kenntnis über Arrays. Jetzt ist mir schon einiges klarer, was da wohl passiert...

Nun zu dem Bug. Danke, dass du dich damit beschäftigst. Leider funktioniert deine Lösung bei mir nicht. Wenn 150 Sekunden vergangen sind (so teste ich es mit ner Batch, die nach dieser Zeit die EXE startet), funktioniert es nach wie vor nicht... Zur Sicherheit hier mal der Auszug aus dem Code, in den ich das eingefügt habe:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
//Channel erstellen und registrieren
IpcChannel ipc = new IpcChannel();
ChannelServices.RegisterChannel(ipc, false);

// LeaseTime auf 1 Jahr setzen
LifetimeServices.LeaseTime = TimeSpan.FromDays(365); // TimeSpan.MaxValue creates ArgumentOutOfRangeException

//"Vermittlungsobjekt" holen (wurde von der ersten Instanz erstellt)
ArgContainer ac = (ArgContainer)Activator.GetObject(typeof(ArgContainer), "ipc://IPCDemo/ArgContainer");


Hast du noch ne Idee? Ich hab zurzeit ne Krücke mit der Batch-Datei, die alle zwei Minuten (da geht es noch...) die EXE ausführt, als "keep alive" sozusagen. Aber es wäre natürlich super, wenn sich der Fehler abstellen lassen würde...

LG
Max

Moderiert von user profile iconTh69: Code- durch C#-Tags ersetzt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4262
Erhaltene Danke: 912

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Mi 01.04.20 07:42 
Du hast es in der falschen Datei (d.h. Methode) eingefügt - der Code muß in die "Form1.cs"-Methode Form_Load.

Es gibt wohl noch eine weitere Möglichkeit, die Lebenszeit des Server-Objektes zu setzen und zwar per Überschreiben der InitializeLifetimeService-Methode in der ArgContainer-Klasse (welche von MarshalByRefObject erbt):
ausblenden C#-Quelltext
1:
2:
3:
4:
public override object InitializeLifetimeService()
{
    return null;
}

Dies soll die Lebenszeit auf "unendlich" setzen.

Alternativ habe ich noch in .NET Remoting with an easy example folgenden Code gefunden:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
public override object InitializeLifetimeService()
{
    ILease lease = (ILease)base.InitializeLifetimeService();

    if (lease.CurrentState == LeaseState.Initial)
    {
        // set times very short for demonstration purposes
        lease.InitialLeaseTime = TimeSpan.FromSeconds(25);
        lease.SponsorshipTimeout = TimeSpan.FromSeconds(25);
        lease.RenewOnCallTime = TimeSpan.FromSeconds(20);
    }
    return lease;
}

Ich habe aber beides noch nicht ausprobiert. Dies hätte aber den Vorteil, daß es nicht die globale Eigenschaft LifetimeServices.LeaseTime verändert (welche u.U. mit anderem Code in Konflikt stände).


Zuletzt bearbeitet von Th69 am Mi 01.04.20 13:27, insgesamt 2-mal bearbeitet

Für diesen Beitrag haben gedankt: Leitstelle_V
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4262
Erhaltene Danke: 912

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Mi 01.04.20 08:09 
Ich habe nun mal den Code von Christian aktualisiert (für VS 2015 und höher) und verbessert (als Anhang).
Die gesamte IPC-Funktionalität habe ich in eine eigene (generische) Klasse IpcService<T> (in einem eigenen Namespace Services) verschoben und die Aufrufe finden nur noch in der Main-Methode statt (anstatt auf 2 Code-Teile verstreut).

Die Main sieht dann so aus (und keine IPC-Funktionalität mehr in der Form_Load):
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
[STAThread]
static void Main()
{
  var ipcService = new IpcService<ArgContainer>("IPCDemo");

  bool createdNew;

  Mutex m = new Mutex(true"3E4FEDBE-1167-4F25-A25E-B43B12EFA8D9"out createdNew);
  if (createdNew)
  {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    var mainForm = new MainForm();

    ArgContainer ac = ipcService.CreateServer();

    // Delegat zuweisen
    ac.OnAddArgs += mainForm.InvokeAddFilesOrFolders;
        
    Application.Run(mainForm);
    m.ReleaseMutex();
  }
  else
  {
    ArgContainer ac = ipcService.GetClientData();

    // Delegaten mit korrektem Parameter aufrufen
    //ac.OnAddArgs(Environment.GetCommandLineArgs());

    var onAddArgs = ac.OnAddArgs;
    if (onAddArgs != null)
      onAddArgs(Environment.GetCommandLineArgs());
    else
      MessageBox.Show("Fehler: Delegate 'OnAddArgs' ist null!");
  }
}


Die LeaseTime ist standardmäßig auf ein Jahr gesetzt und kann aber per
ausblenden C#-Quelltext
1:
IpcService<ArgContainer>.LeaseTime = timespan;					

verändert werden (vor dem Aufruf von CreateServer!).
Einloggen, um Attachments anzusehen!

Für diesen Beitrag haben gedankt: Leitstelle_V
Leitstelle_V
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Mi 01.04.20 18:07 
Lieber Th69,

ich danke dir vielmals. Es scheint alles zu funktionieren. Ich setz mich jetzt mal ran für mein eigenes Programm :-).

Eine Frage noch, diesen "Bug" hier hast du mit deiner neuen Version gleich mit gefixt oder?:

user profile iconChristian S. hat folgendes geschrieben Zum zitierten Posting springen:
Es hat mich jetzt doch interessiert. Das Problem ist, dass die "späteren" Clients (in der program.cs) alle einen Channel mit Port "IPCDemoClient" aufmachen. Das geht aber nur einmal.

Die Lösung ist einfach: man lässt den Port-Namen weg, wir brauchen hier nur einen Client-Channel und der braucht keinen Port-Namen. Aus
ausblenden C#-Quelltext
1:
IpcChannel ipc = new IpcChannel("IPCDemoClient");					

wird
ausblenden C#-Quelltext
1:
IpcChannel ipc = new IpcChannel();					

und es sollte funktionieren :)
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4262
Erhaltene Danke: 912

Win10
C#, C++ (VS 2015/17)
BeitragVerfasst: Do 02.04.20 08:23 
Ja, das habe ich auch noch gestern gesehen und gefixt (daher "Rev[ision] 1").

Für diesen Beitrag haben gedankt: Leitstelle_V
Leitstelle_V
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Do 02.04.20 08:24 
Großartig, danke :)