[de] Ein Aufrufziel hat einen Ausnahmefehler verursacht.

Topics: Technical Support
Feb 28, 2012 at 3:07 PM
Edited Feb 28, 2012 at 3:20 PM

Hallo,

erst einmal vielen Dank an die Community, für die tolle Arbeit.

Zur zeit versuche ich ein Tool (noch in Delphi programmiert), über welches meine Programme im Netz kommunizieren, durch euer Framework zu ersetzten.

Leider stelle ich mich da nicht gerade clever an.

Als Informationsquelle nutze ich das Beispielprojekt "MiniChat". Statt <string, string> sende und empfange ich <int, string>.

Folgender Quelltext definiert die Schnittstelle auf dem Server:

namespace DBAccess
{
   public interface IDBAccess
   {
      event Action<int, string> DataRecv;

      void SetData(int Idx, string text);
      string GetData(int Idx);
   }

   public class CDBAccess : IDBAccess
   {
      string[] Array = new string[100];

      public event Action<int, string> DataRecv;

      public void SetData(int Idx, string text)
      {
         Array[Idx] = text;

         if (DataRecv != null)
            DataRecv(Idx, text);
      }

      public string GetData(int Idx)
      {
         return Array[Idx];
      }
   }
}
...

InitializeComponent();
host = new ZyanComponentHost("DBAccess", 9010);
host.RegisterComponent<IDBAccess, CDBAccess>(ActivationType.Singleton);
Der Client hat eine Klasse, die die Kommunikation beinhaltet:
namespace DBAccess
{
	public interface IDBAccess
	{
		event Action<int, string> DataRecv;

		void SetData(int Idx, string text);
		string GetData(int Idx);
	}

	public struct RecvItem
	{
		public int Idx;
		public string Data;

		public RecvItem(int Idx, string Data)
		{
			this.Idx = Idx;
			this.Data = Data;
		}
	}

	class CDBAccess_Client
	{
		ZyanConnection ZC;
		IDBAccess DBAccessInterface;

		public event EventHandler Received;

		public CDBAccess_Client()
		{
			try{
				ReConnect();
			}catch{}
		}

		public void ReConnect()
		{
			ZC = new ZyanConnection("tcp://localhost:9010/DBAccess");
			DBAccessInterface = ZC.CreateProxy<IDBAccess>();
			DBAccessInterface.DataRecv += new Action<int, string>(DBAccessInterface_DataRecv);
		}

		public void WriteDB(int Idx, string Data)
		{
			DBAccessInterface.SetData(Idx, Data);
		}

		public string ReadDB(int Idx)
		{
			return DBAccessInterface.GetData(Idx);
		}

		void DBAccessInterface_DataRecv(int Idx, string Data)
		{
			Received(new RecvItem(Idx,Data), new EventArgs());
		}
	}
}
 
wird .GetData(...) oder .SetData(...) aufgerufen, kommt der Fehler:
"Ein Aufrufziel hat einen Ausnahmefehler verursacht"
Was habe ich falsch gemacht?
Entschuldigt bitte die Menge Quelltext.
Schonmal vielen Dank!
Gruß
Christian

Coordinator
Feb 29, 2012 at 7:41 PM
Edited Feb 29, 2012 at 8:00 PM

Hi Christian!

I'm sorry, Rainbird seems to be unavailable at the moment, and I don't speak German, so I'll answer in English.

First of all, I couldn't reproduce the error that you have.
I copied all your code, added some missing parts (like Program classes), and everything seems to work fine.

Complete server code: http://pastebin.com/UZ15ABck
Complete client code: http://pastebin.com/pY1aGg3J

My version runs with no errors.
If you want me to reproduce the error, please send a complete copy of your code.

A few thoughts:

1. You seem to get "Exception has been thrown by the target of an invocation‎" exception. It could mean virtually anything. To see the real cause of your error, please examine the InnerException property of the exception you have caught (there can be many InnerExceptions, so you may wish to display them all):

try
{
     ... // your code that throws an exception
}
catch (Exception ex)
{
     // dump with all inner exceptions to the console
     var exception = ex;
     while (exception != null)
     {
         Console.WriteLine("Exception: {0}", exception);
         Console.WriteLine("Message:   {0}", exception.Message);
         exception = exception.InnerException;
     }
}

2. Looks like you define IDBAccess on both client and server. This is wrong: in fact, CLR thinks they are different because they reside in different assemblies. Please create a separate project (shared assembly) and move your interface there. Both the client and the server should use the same interface definition from that shared assembly. See MiniChat solution for the proper example.

Regards, yallie.

Mar 1, 2012 at 3:49 PM

Hello Yallie,

thanks for spending time on my issue!

I had created a separate project to implement the interface (IDBAccess). Then i included the DLL-file in my client- and server application. Now it works :-) Thanks for  your helpful informations.

Regards,
Christian