diff --git a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
index 99945820..a02a7374 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ClientAPI.cs
@@ -1459,6 +1459,65 @@ namespace IEC61850
return newList;
}
+
+ ///
+ /// Read object handler.
+ ///
+ /// The invoke ID of the reqeust triggering this callback
+ /// user provided callback parameter
+ /// Error code of response or timeout error in case of a response timeout
+ /// The read result value or null in case of an error
+ public delegate void ReadValueHandler(UInt32 invokeId, object parameter, IedClientError err, MmsValue value);
+
+ private void nativeReadObjectHandler (UInt32 invokeId, IntPtr parameter, int err, IntPtr value)
+ {
+ GCHandle handle = GCHandle.FromIntPtr(parameter);
+
+ Tuple callbackInfo = handle.Target as Tuple;
+
+ ReadValueHandler handler = callbackInfo.Item1;
+ object handlerParameter = callbackInfo.Item2;
+
+ handle.Free();
+
+ IedClientError clientError = (IedClientError)err;
+
+ MmsValue mmsValue = null;
+
+ if (value != IntPtr.Zero)
+ {
+ mmsValue = new MmsValue(value, true);
+ }
+
+ handler(invokeId, handlerParameter, clientError, mmsValue);
+ }
+
+ /// Asynchronously read the value of a data attribute (DA) or functional constraint data object (FCDO).
+ /// The object reference of a DA or FCDO.
+ /// The functional constraint (FC) of the object
+ /// Callback function to handle the received response or service timeout
+ /// User provided callback parameter. Will be passed to the callback function
+ /// the invoke ID of the sent request
+ /// This exception is thrown if there is a connection or service error
+ public UInt32 ReadValueAsync(string objectReference, FunctionalConstraint fc, ReadValueHandler handler, object parameter)
+ {
+ int error;
+
+ Tuple callbackInfo = Tuple.Create(handler, parameter);
+
+ GCHandle handle = GCHandle.Alloc(callbackInfo);
+
+ UInt32 invokeId = IedConnection_readObjectAsync(connection, out error, objectReference, (int)fc, nativeReadObjectHandler, GCHandle.ToIntPtr(handle));
+
+ if (error != 0)
+ {
+ handle.Free();
+ throw new IedConnectionException("Reading value failed", error);
+ }
+
+ return invokeId;
+ }
+
internal void UninstallReportHandler (string objectReference)
{
if (connection != IntPtr.Zero) {
diff --git a/dotnet/client_example_async/Program.cs b/dotnet/client_example_async/Program.cs
new file mode 100644
index 00000000..1bedc751
--- /dev/null
+++ b/dotnet/client_example_async/Program.cs
@@ -0,0 +1,105 @@
+using System;
+using IEC61850.Client;
+using IEC61850.Common;
+using System.Threading;
+
+namespace client_example_async
+{
+ class MainClass
+ {
+
+ public static void Main (string[] args)
+ {
+ IedConnection con = new IedConnection ();
+
+ string hostname;
+
+ if (args.Length > 0)
+ hostname = args[0];
+ else
+ hostname = "127.0.0.1";
+
+ int port = 102;
+
+ if (args.Length > 1)
+ port = Int32.Parse(args [1]);
+
+ Console.WriteLine("Connect to " + hostname);
+
+ try
+ {
+ con.Connect(hostname, port);
+
+ /* read FCDO */
+ con.ReadValueAsync("simpleIOGenericIO/GGIO1.AnIn1", FunctionalConstraint.MX, delegate(uint invokeId, object parameter, IedClientError err, MmsValue value) {
+
+ if (err == IedClientError.IED_ERROR_OK)
+ {
+ if (value.GetType() == MmsType.MMS_STRUCTURE)
+ {
+ Console.WriteLine("Value is of complex type");
+
+ for (int i = 0; i < value.Size(); i++)
+ {
+ Console.WriteLine(" element: " + value.GetElement(i).GetType());
+ if (value.GetElement(i).GetType() == MmsType.MMS_UTC_TIME)
+ {
+ Console.WriteLine(" -> " + value.GetElement(i).GetUtcTimeAsDateTimeOffset());
+ }
+ }
+ }
+ }
+ else {
+ Console.WriteLine("Read error: " + err.ToString());
+ }
+
+
+ }, null);
+
+ con.ReadValueAsync("simpleIOGenericIO/GGIO1.AnIn1", FunctionalConstraint.MX, delegate(uint invokeId, object parameter, IedClientError err, MmsValue value) {
+
+ if (err == IedClientError.IED_ERROR_OK)
+ {
+ if (value.GetType() == MmsType.MMS_STRUCTURE)
+ {
+ Console.WriteLine("Value is of complex type");
+
+ for (int i = 0; i < value.Size(); i++)
+ {
+ Console.WriteLine(" element: " + value.GetElement(i).GetType());
+ if (value.GetElement(i).GetType() == MmsType.MMS_UTC_TIME)
+ {
+ Console.WriteLine(" -> " + value.GetElement(i).GetUtcTimeAsDateTimeOffset());
+ }
+ }
+ }
+ }
+ else {
+ Console.WriteLine("Read error: " + err.ToString());
+ }
+
+
+ }, null);
+
+
+ // Thread.Sleep(5000);
+
+ con.Abort();
+ }
+ catch (IedConnectionException e)
+ {
+ Console.WriteLine(e.Message);
+ }
+
+ System.Threading.Thread.Sleep(2000);
+
+ // release all resources - do NOT use the object after this call!!
+ con.Dispose ();
+ }
+
+ static void HandleReadObjectHandler (uint invokeId, object parameter, IedClientError err, MmsValue value)
+ {
+
+ }
+ }
+}
diff --git a/dotnet/client_example_async/Properties/AssemblyInfo.cs b/dotnet/client_example_async/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..e909bebd
--- /dev/null
+++ b/dotnet/client_example_async/Properties/AssemblyInfo.cs
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("client_example_async")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("mzillgit")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/dotnet/client_example_async/client_example_async.csproj b/dotnet/client_example_async/client_example_async.csproj
new file mode 100644
index 00000000..17879d2c
--- /dev/null
+++ b/dotnet/client_example_async/client_example_async.csproj
@@ -0,0 +1,44 @@
+
+
+
+ Debug
+ AnyCPU
+ {71902641-776A-47D8-9C0E-9ACBBEAC1370}
+ Exe
+ client_example_async
+ client_example_async
+ v4.5
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ true
+
+
+ full
+ true
+ bin\Release
+ prompt
+ 4
+ true
+
+
+
+
+
+
+
+
+
+
+
+ {C35D624E-5506-4560-8074-1728F1FA1A4D}
+ IEC61850.NET
+
+
+
\ No newline at end of file
diff --git a/dotnet/dotnet.sln b/dotnet/dotnet.sln
index 97feef4c..c2ab42d8 100644
--- a/dotnet/dotnet.sln
+++ b/dotnet/dotnet.sln
@@ -46,6 +46,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tls_server_example", "tls_s
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "client_example_setting_groups", "client_example_setting_groups\client_example_setting_groups.csproj", "{0DA95476-B149-450B-AC36-01CEECFC1A43}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "client_example_async", "client_example_async\client_example_async.csproj", "{71902641-776A-47D8-9C0E-9ACBBEAC1370}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -92,6 +94,10 @@ Global
{71485F99-2976-45E6-B73D-4946E594C15C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{71485F99-2976-45E6-B73D-4946E594C15C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{71485F99-2976-45E6-B73D-4946E594C15C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {71902641-776A-47D8-9C0E-9ACBBEAC1370}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {71902641-776A-47D8-9C0E-9ACBBEAC1370}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {71902641-776A-47D8-9C0E-9ACBBEAC1370}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {71902641-776A-47D8-9C0E-9ACBBEAC1370}.Release|Any CPU.Build.0 = Release|Any CPU
{77127456-19B9-4D1A-AEF9-40F8D1C5695E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77127456-19B9-4D1A-AEF9-40F8D1C5695E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77127456-19B9-4D1A-AEF9-40F8D1C5695E}.Release|Any CPU.ActiveCfg = Release|Any CPU