Laden...
D
D12
myCSharp.de - Member
6
Themen
22
Beiträge
Letzte Aktivität
vor 19 Jahren
Dabei seit
28.06.2005
Alter
56
Erstellt vor 19 Jahren

Hallo Leute,

ich bin bei der Entwicklung einer verteilten Anwendung auf ein Problem gestoßen, bei dem ich nicht weiter komme.

Aufgabenstellung:
Ein Zählwerk sammelt Daten aus einer IO und wertet dieses in verschiedenen Daten-Objekten aus. Dazu gehören strings, integer und ein- sowie mehrdimensionale integer arrays.

Die verteilte Anwendung besteht aus vier Komponenten:

  1. RemoteObject, das alle Daten des Zählwerkes verarbeitet.
  2. RemoteServer, stellt das RemoteObject als Singleton zur Verfügung.
  3. RemoteClient, stellt das Zählwerk aus dem Remote-Object in Balkendiagrammen visuell dar.
  4. IOservice, wertet die Signale der IO aus, spaltet diese in gesetzte Bits und übergibt jedes einzelne Bit an das Remote-Object.

Ein direkter Zugriff auf die Member des Remote-Objects ist nicht zulässig, wenn ich das versuche kommt logischerweise folgende Meldung:

MainForm.cs(948,18): error CS0197: 'MyRemoteService.MyService.ctrA' kann als Verweis oder Ausgabe nicht weitergegeben werden, weil 'MyRemoteService.MyService.ctrA' eine Marshal-bei-Verweisklasse ist

Also hat jeder Member eine eigene Methode für die Rückgabe bekommen. Ein Beispiel:

public int MeineMethode()
{
  return this.x;  //*** X ist ein Beispiel, meine Member haben natürlich aussägekräftigere Namen
}

Die Methode habe ich dann vom Client aufgerufen:

int x = ro.MeineMethode();  //*** ro stellt mein RemoteObject dar!

So weit funktioniert auch alles. Aber nach einiger Zeit wird das System schwerfällig, weil die Anwendungen den Speicher regelrecht auffressen.

Meine Vermutung war das die Rückgabe-Variablen vom GarbageCollector nicht ordnungsgemäß zerstört werden.

Also habe ich mit CallByReference gearbeitet, damit die Variable nicht bei jedem Aufruf neu erzeugt wird. Denn meine Maske arbeitet mit einem Timer, der bis zu 4x pro Sekunde die Maske aktualisiert.

Neue Lösung:

public void MeineMethode(ref int tmp)
{
  tmp = this.x;
}

So sah dann der Aufruf in etwa aus:

int x;
ro.MeineMethode(ref x);

Es hat den selben Erfolg, mein Programm läuft, aber die Speicherprobleme bestehen weiterhin. Ich brauche dringend die nötige Hilfe, da ich nicht mehr weiter komme.

So, mal schauen ob hier einer weiter weis oder ob ich noch tagelang testen, debuggen, Bücher suchen, Bücher lesen und verzweifeln muss.

cu soon
D12

Erstellt vor 19 Jahren

so stehts in den Büchern!

Erstellt vor 19 Jahren

Singleton weil das Object als Instanz aufgerufen wird und nicht als neue Object, so bleiben die Inhalte der Member erhalten,... Bei Single werden die Inhalte mit jeder neuen Instanz initialisiert.

Erstellt vor 19 Jahren

Hmm... Hab ich quasi alles so gemacht, einiziger Unterschied ist das ich als Host kein Konsolen-Proggy habe, sondern ein Windwos-Dienst. Er lässt mich nicht an das Objekt ran, das Einbinden funzt nicht.

Visual Studio.NET -> Hab ich nie mit gearbeitet, nicht jeder hat das Glück in einem großen Konzern zu arbeiten. Bin freischaffend, leider!

Kannst nicht mal über meinen Code drüberschauen, ich komm nicht weiter, würde sogar was dafür zahlen....

Erstellt vor 19 Jahren

Hi,

das ist plausibel, habe aber noch das Problem, das ich mit dem Object, dem Serice und dem Client durcheinander komme. Was muss da wo hin?

LG D12

Erstellt vor 19 Jahren

Hallo Rainbird,

das sieht sehr plausibel aus. Leider finde ich keinen Namespace in dem "Businesslogic" sich wohl fühlen möchte.

Welches USING brauche ich hier?

LG D12

Erstellt vor 19 Jahren

Hallo Leute,

ich verzweifel langsam am Remoting!

Vorweg: Ich habe noch nie mit Remoting gearbeitet!

Anforderung:
Ein IO-Gerät wird von einem Dienst ausgelesen und die Daten sollen für eine unbestimmte Anzahl Clients ausgewertet und aufbereitet werden. Die Clients müssen die Daten direkt aus dem Arbeitsspeicher des Rechners an dem das IO-Gerät hängt lesen.

Lösungsansatz zu Testzwecken für Remoting:

class IOcounter : MarshalByRefObject
class IOserver : System.ServiceProcess.ServiceBase (Windows Dienst)
class IOconsole

Object IOcounter wird vom Windows-Dienst IOserver sauber erstellt und ein Zähler arbeitet über einen Timer.

Nun soll der Client den Zähler auslesen können und das so, das mehrere Clients darauf zugreigen können. (Threading wird mein nächstes Problem sein!)

Folgende Source macht mir Kopfzerbrechen:

RemotingConfiguration.RegisterActivatedClientType
            (typeof (IOcounter), "tcp://localhost:1234");
        IOcounter ioc = new IOcounter();

Erstellt eine neue Instanz, bei der der Zähler auf 0 steht, weil er neu deklariert und initialisiert wird.

erarbeitete Lösung aus dem .NET-Entwicklerbch von MS-Press:

IOcounter ioc = (IOcounter) Activator.GetObject(			typeof  (IOcounter), "tcp://localhost:1234/IOcounter");

Irgendwas fehlt noch!
Er kann starten, meldet aber folgenden Fehler direkt nach Start:


Unbehandelte Ausnahme: System.Runtime.Remoting.RemotingException: Angeforderter
Dienst wurde nicht gefunden

Server stack trace:
   at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(
IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders reques
tHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& respon
seHeaders, Stream& responseStream)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage req
Msg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgDa
ta, Int32 type)
   at IOcounter.wert()
   at IOconsole.Main()
Drücken Sie eine beliebige Taste . . .

Nun häng ich schon seit drei Tagen mit dem Mist rum und komme nicht weiter...
Vielleicht braucht Ihr für eine Hilfe die kompletten Sourcen?
Die Sourcen habe ich --> hier <-- als *.rar verpackt!

Bin für jede sinnvolle Hilfe dankbar!

cu s00n!:
D12

Und bitte keine Antworten in denen mir mitgeteilt wird, das es Bücher gibt oder Lehrgänge. Bücher habe ich schon eine Menge und Lehrgänge war ich auch schon in vielen...

Erstellt vor 19 Jahren

**Hallo Herbivore, **

danke, das war erst einmal hilfreich.

Mittlerweile bin ich soweit, das ich einen Dienst installiert bekomme. Aber es hat noch Probleme.

Obwohl ich den Dienst mit dem Namen TestDienst benenne, wird dieser nur als „Hello Service Template“ in den Diensten angezeigt.

Wenn ich diesen Dienst starte, dann wird der definierte Code in der Methode „OnStart“ nicht ausgeführt, dieser soll als Zähler Werte in eine Datei schreiben!

Hier ist der dazugehörige Code. Vielleicht weis hier wer, was ich falsch gemacht habe?

using System;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Configuration.Install;
using System.Windows.Forms;

namespace testdienst
{
  /// <summary>
  /// This is the class for my Service
  /// </summary>
  public class MyService : System.ServiceProcess.ServiceBase
  {
    public MyService()
    {
       InitializeComponents();
       this.ServiceName = "TestDienst";
       ProjectInstaller pi = new ProjectInstaller();

       // TODO: Add any further initialization code
    }

     private void InitializeComponents()
     {
        this.ServiceName = "TestDienst";
     }
		
     /// <summary>
     /// This method starts the service.
     /// </summary>
     public static void Main()
     {
        System.ServiceProcess.ServiceBase.Run(new System.ServiceProcess.ServiceBase[]
        {
           new MyService() // To run more than one service you have to add them here	
        });
     }

     /// <summary>
     /// Clean up any resources being used.
     /// </summary>
     protected override void Dispose(bool disposing)
     {
        // TODO: Add cleanup code here (if required)
        base.Dispose(disposing);
     }

     /// <summary>
     /// Start this service.
     /// </summary>
     protected override void OnStart(string[] args)
     {
        StreamWriter sw;
        int i = 1;
        if ( !File.Exists("c:\test.txt"))
        {//*** Wenn die Datei für den Test nicht existiert, dann soll die neu angelegt werden
           sw = new StreamWriter(File.Open("c:\test.txt", FileMode.Create));
           sw.WriteLine("Das ist ein Test");
           sw.Close();
        }	
        //*** Hier wird ein Zähler von 1 bis 1000 in die Datei geschrieben
        sw = new StreamWriter(File.Open("c:\test.txt", FileMode.Append));
        while (i<1000)
        {
           sw.Write(i.ToString() + " ");
           i++;
        }
        sw.Close();
     }
 
     /// <summary>
     /// Stop this service.
     /// </summary>
     protected override void OnStop()
     {
        // TODO: Add tear-down code here (if required) 
        //       to stop your service.
     }
  }
}

[RunInstaller(true)]
public class ProjectInstaller : Installer
{
   ServiceInstaller si = new ServiceInstaller();
	
   public ProjectInstaller()
   {
      ServiceProcessInstaller spi = new ServiceProcessInstaller();
      spi.Account = ServiceAccount.LocalSystem;	

      ServiceInstaller si = new ServiceInstaller();
      si.ServiceName = "TestDienst";
      si.StartType = ServiceStartMode.Automatic;
      Installers.AddRange(new Installer[] {spi, si});
   }
	
   public override void Install(IDictionary stateServer)
   {
      base.Install(stateServer);
      Microsoft.Win32.RegistryKey desc;
      try
      {			
         desc = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
            "System\CurrentControlSet\Services\" + si.ServiceName, true);
         desc.SetValue("Description", "Das ist ein erster Testdienst");
         desc.Close();
      }
      catch(Exception ex)
      {
         MessageBox.Show(ex.ToString());
      }
   }
	
   protected override void OnAfterInstall(IDictionary savedState)
   {
      base.OnAfterInstall(savedState);
      Microsoft.Win32.RegistryKey image;
      try
      {
         image = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
            "System\CurrentControlSet\Services\" + si.ServiceName, true);
         si.ServiceName = "TestDienst";
         image.SetValue("ImagePath", image.GetValue("ImagePath") + " - Service");
         image.Close();
      }
      catch(Exception ex)
      {
         MessageBox.Show(ex.ToString());
      }
   }
}

LG D12

Erstellt vor 19 Jahren

Hallo Herbivore,

welche SDK Doku? Die von Microsoft, das MSDN?

LG D12

Erstellt vor 19 Jahren

Hallo myCsharp.de,

kann mir hier einer anhand eines kurzen Beispiels zeigen, wie man mit #develope einen Dienst erstellt und nach erstellen des Combines installiert, so das man diesen Testen kann?

Link zu einem guten Tutorial wäre auch praktisch...

Der Dienst sollte später wie jeder Dienst über die Dienst-Verwaltung im Windows 2k/Xp zu bedienen sein.

Danke,
D12

10 von 22 Beiträgen