From 8a18313d28341db1287bed3e4525b9d66c46db7a Mon Sep 17 00:00:00 2001 From: timyhac Date: Sun, 23 Jan 2022 10:52:53 +1100 Subject: [PATCH 1/7] Added TryXYZ methods on NativeTagWrapper --- src/libplctag.Tests/AsyncTests.cs | 56 ++++++++++++- src/libplctag.Tests/libplctag.Tests.csproj | 2 +- src/libplctag/NativeTagWrapper.cs | 92 +++++++++++++++------- 3 files changed, 117 insertions(+), 33 deletions(-) diff --git a/src/libplctag.Tests/AsyncTests.cs b/src/libplctag.Tests/AsyncTests.cs index 03eea7fb..a882fa0c 100644 --- a/src/libplctag.Tests/AsyncTests.cs +++ b/src/libplctag.Tests/AsyncTests.cs @@ -59,16 +59,66 @@ public async Task Timeout_throws_a_LibPlcTagException() }; // Act - - - // Assert var ex = await Assert.ThrowsAsync(async () => { await tag.InitializeAsync(); }); + // Assert Assert.Equal(Status.ErrorTimeout.ToString(), ex.Message); } + [Fact] + public async Task TryInitialize_returns_an_ErrorTimeout() + { + // Arrange + var nativeTag = new Mock(); + + nativeTag // The initial creation of the tag object returns a status, so we return pending + .Setup(m => m.plc_tag_create(It.IsAny(), 0)) + .Returns((int)Status.Pending); + + nativeTag // Subsequent calls to determine the tag status should still return pending + .Setup(m => m.plc_tag_status(It.IsAny())) + .Returns((int)Status.Pending); + + var tag = new NativeTagWrapper(nativeTag.Object) + { + Timeout = REALISTIC_TIMEOUT_FOR_ALL_OPERATIONS + }; + + // Act + var result = await tag.TryInitializeAsync(); + + // Assert + Assert.Equal(Status.ErrorTimeout, result); + } + + [Fact] + public async Task TryInitialize_Cancelled_cancellation_token_throws_a_TaskCanceledException() + { + // Arrange + var nativeTag = new Mock(); + + nativeTag // The initial creation of the tag object returns a status, so we return pending + .Setup(m => m.plc_tag_create(It.IsAny(), 0)) + .Returns((int)Status.Pending); + + nativeTag // Subsequent calls to determine the tag status should still return pending + .Setup(m => m.plc_tag_status(It.IsAny())) + .Returns((int)Status.Pending); + + var tag = new NativeTagWrapper(nativeTag.Object); + var cts = new CancellationTokenSource(); + + // Act + cts.CancelAfter(REALISTIC_TIMEOUT_FOR_ALL_OPERATIONS); + + // Assert + await Assert.ThrowsAsync(async () => { + await tag.TryInitializeAsync(cts.Token); + }); + } + [Fact] public async Task Timeout_returns_pending_but_eventually_ok() { diff --git a/src/libplctag.Tests/libplctag.Tests.csproj b/src/libplctag.Tests/libplctag.Tests.csproj index e87c0cdc..ad3752d1 100644 --- a/src/libplctag.Tests/libplctag.Tests.csproj +++ b/src/libplctag.Tests/libplctag.Tests.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 false diff --git a/src/libplctag/NativeTagWrapper.cs b/src/libplctag/NativeTagWrapper.cs index ec5c1fdd..79ae6de8 100644 --- a/src/libplctag/NativeTagWrapper.cs +++ b/src/libplctag/NativeTagWrapper.cs @@ -286,7 +286,43 @@ public void Abort() public void Initialize() { + var status = TryInitialize(); + ThrowIfStatusNotOk(status); + } + + public async Task InitializeAsync(CancellationToken token = default) + { + var status = await TryInitializeAsync(token); + ThrowIfStatusNotOk(status); + } + + public void Read() + { + var status = TryRead(); + ThrowIfStatusNotOk(status); + } + public async Task ReadAsync(CancellationToken token = default) + { + var status = await TryReadAsync(token); + ThrowIfStatusNotOk(status); + } + + public void Write() + { + var status = TryWrite(); + ThrowIfStatusNotOk(status); + } + + public async Task WriteAsync(CancellationToken token = default) + { + var status = await TryWriteAsync(token); + ThrowIfStatusNotOk(status); + } + + + public Status TryInitialize() + { ThrowIfAlreadyDisposed(); ThrowIfAlreadyInitialized(); @@ -296,18 +332,19 @@ public void Initialize() var result = _native.plc_tag_create(attributeString, millisecondTimeout); if (result < 0) - throw new LibPlcTagException((Status)result); + return (Status)result; else nativeTagHandle = result; SetUpEvents(); _isInitialized = true; + + return (Status)result; } - public async Task InitializeAsync(CancellationToken token = default) + public async Task TryInitializeAsync(CancellationToken token = default) { - ThrowIfAlreadyDisposed(); ThrowIfAlreadyInitialized(); @@ -325,11 +362,11 @@ public async Task InitializeAsync(CancellationToken token = default) if (token.IsCancellationRequested) readTask.SetCanceled(); else - readTask.SetException(new LibPlcTagException(Status.ErrorTimeout)); + readTask.TrySetResult(Status.ErrorTimeout); } })) { - var readTask = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + var readTask = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); readTasks.Push(readTask); var attributeString = GetAttributeString(); @@ -344,11 +381,12 @@ public async Task InitializeAsync(CancellationToken token = default) await readTask.Task; _isInitialized = true; + + return readTask.Task.Result; } } } - - public void Read() + public Status TryRead() { ThrowIfAlreadyDisposed(); InitializeIfRequired(); @@ -356,10 +394,11 @@ public void Read() var millisecondTimeout = (int)Timeout.TotalMilliseconds; var result = (Status)_native.plc_tag_read(nativeTagHandle, millisecondTimeout); - ThrowIfStatusNotOk(result); + + return result; } - public async Task ReadAsync(CancellationToken token = default) + public async Task TryReadAsync(CancellationToken token = default) { ThrowIfAlreadyDisposed(); @@ -378,19 +417,19 @@ public async Task ReadAsync(CancellationToken token = default) if (token.IsCancellationRequested) readTask.SetCanceled(); else - readTask.SetException(new LibPlcTagException(Status.ErrorTimeout)); + readTask.SetResult(Status.ErrorTimeout); } })) { - var readTask = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + var readTask = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); readTasks.Push(readTask); _native.plc_tag_read(nativeTagHandle, TIMEOUT_VALUE_THAT_INDICATES_ASYNC_OPERATION); await readTask.Task; + return readTask.Task.Result; } } } - - public void Write() + public Status TryWrite() { ThrowIfAlreadyDisposed(); InitializeIfRequired(); @@ -398,10 +437,10 @@ public void Write() var millisecondTimeout = (int)Timeout.TotalMilliseconds; var result = (Status)_native.plc_tag_write(nativeTagHandle, millisecondTimeout); - ThrowIfStatusNotOk(result); + return result; } - public async Task WriteAsync(CancellationToken token = default) + public async Task TryWriteAsync(CancellationToken token = default) { ThrowIfAlreadyDisposed(); @@ -420,14 +459,15 @@ public async Task WriteAsync(CancellationToken token = default) if (token.IsCancellationRequested) writeTask.SetCanceled(); else - writeTask.SetException(new LibPlcTagException(Status.ErrorTimeout)); + writeTask.SetResult(Status.ErrorTimeout); } })) { - var writeTask = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + var writeTask = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); writeTasks.Push(writeTask); _native.plc_tag_write(nativeTagHandle, TIMEOUT_VALUE_THAT_INDICATES_ASYNC_OPERATION); await writeTask.Task; + return writeTask.Task.Result; } } } @@ -703,41 +743,35 @@ void RemoveEvents() } - private readonly ConcurrentStack> readTasks = new ConcurrentStack>(); + private readonly ConcurrentStack> readTasks = new ConcurrentStack>(); void ReadTaskCompleter(object sender, TagEventArgs e) { if (readTasks.TryPop(out var readTask)) { switch (e.Status) { - case Status.Ok: - readTask?.SetResult(null); - break; case Status.Pending: - // Do nothing, wait for another ReadCompleted callback when Status is Ok. + // Do nothing, wait for another ReadCompleted callback break; default: - readTask?.SetException(new LibPlcTagException(e.Status)); + readTask?.SetResult(e.Status); break; } } } - private readonly ConcurrentStack> writeTasks = new ConcurrentStack>(); + private readonly ConcurrentStack> writeTasks = new ConcurrentStack>(); void WriteTaskCompleter(object sender, TagEventArgs e) { if (writeTasks.TryPop(out var writeTask)) { switch (e.Status) { - case Status.Ok: - writeTask?.SetResult(null); - break; case Status.Pending: - // Do nothing, wait for another WriteCompleted callback when Status is Ok. + // Do nothing, wait for another WriteCompleted callback break; default: - writeTask?.SetException(new LibPlcTagException(e.Status)); + writeTask?.SetResult(e.Status); break; } From 14d2dca435eebfc30149631cca3824c6b4921a64 Mon Sep 17 00:00:00 2001 From: timyhac Date: Sun, 23 Jan 2022 11:11:54 +1100 Subject: [PATCH 2/7] Update .NET version --- .github/workflows/build-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index 6b4395dd..12138e56 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -18,7 +18,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: 5.0.x + dotnet-version: 6.0.x - name: Build run: dotnet build './src/' From 5f5754fad2d52fe6144dfe82a9130a08a48e0efe Mon Sep 17 00:00:00 2001 From: timyhac Date: Sun, 23 Jan 2022 11:33:55 +1100 Subject: [PATCH 3/7] Updated .net version --- src/Examples/CSharp DotNetCore/CSharp DotNetCore.csproj | 2 +- src/Examples/CSharp NativeImport/CSharp NativeImport.csproj | 2 +- src/Examples/VB.NET DotNetCore/VB.NET DotNetCore.vbproj | 2 +- .../libplctag.NativeImport.Benchmarks.csproj | 2 +- .../libplctag.NativeImport.Tests.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Examples/CSharp DotNetCore/CSharp DotNetCore.csproj b/src/Examples/CSharp DotNetCore/CSharp DotNetCore.csproj index 8f7ae5fc..b7509311 100644 --- a/src/Examples/CSharp DotNetCore/CSharp DotNetCore.csproj +++ b/src/Examples/CSharp DotNetCore/CSharp DotNetCore.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net6.0 diff --git a/src/Examples/CSharp NativeImport/CSharp NativeImport.csproj b/src/Examples/CSharp NativeImport/CSharp NativeImport.csproj index bf0b0152..13acd297 100644 --- a/src/Examples/CSharp NativeImport/CSharp NativeImport.csproj +++ b/src/Examples/CSharp NativeImport/CSharp NativeImport.csproj @@ -2,7 +2,7 @@ Exe - net5.0 + net6.0 NativeImport_Examples diff --git a/src/Examples/VB.NET DotNetCore/VB.NET DotNetCore.vbproj b/src/Examples/VB.NET DotNetCore/VB.NET DotNetCore.vbproj index 59297548..2f9bbe21 100644 --- a/src/Examples/VB.NET DotNetCore/VB.NET DotNetCore.vbproj +++ b/src/Examples/VB.NET DotNetCore/VB.NET DotNetCore.vbproj @@ -3,7 +3,7 @@ Exe VB.NET_DotNetCore - netcoreapp3.1 + net6.0 diff --git a/src/libplctag.NativeImport.Benchmarks/libplctag.NativeImport.Benchmarks.csproj b/src/libplctag.NativeImport.Benchmarks/libplctag.NativeImport.Benchmarks.csproj index 2eb796ff..f97a3d81 100644 --- a/src/libplctag.NativeImport.Benchmarks/libplctag.NativeImport.Benchmarks.csproj +++ b/src/libplctag.NativeImport.Benchmarks/libplctag.NativeImport.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net6.0 diff --git a/src/libplctag.NativeImport.Tests/libplctag.NativeImport.Tests.csproj b/src/libplctag.NativeImport.Tests/libplctag.NativeImport.Tests.csproj index 205a4c8d..a5f7aacd 100644 --- a/src/libplctag.NativeImport.Tests/libplctag.NativeImport.Tests.csproj +++ b/src/libplctag.NativeImport.Tests/libplctag.NativeImport.Tests.csproj @@ -1,7 +1,7 @@ - net5.0 + net6.0 false From 95dad1b5b70ecec0f5d10b298b0cf3995681666d Mon Sep 17 00:00:00 2001 From: timyhac Date: Tue, 5 Jul 2022 20:56:12 +1000 Subject: [PATCH 4/7] Minor method extraction --- src/libplctag/NativeTagWrapper.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libplctag/NativeTagWrapper.cs b/src/libplctag/NativeTagWrapper.cs index 79ae6de8..fa5b2084 100644 --- a/src/libplctag/NativeTagWrapper.cs +++ b/src/libplctag/NativeTagWrapper.cs @@ -617,10 +617,16 @@ private void ThrowIfAlreadyInitialized() throw new InvalidOperationException("Already initialized"); } + public bool IsStatusOk(Status? status = null) + { + var statusToCheck = status ?? GetStatus(); + return statusToCheck == Status.Ok; + } + private void ThrowIfStatusNotOk(Status? status = null) { var statusToCheck = status ?? GetStatus(); - if (statusToCheck != Status.Ok) + if (!IsStatusOk(status)) throw new LibPlcTagException(statusToCheck); } From 3d492e694df0c31c04c204a0839470287a7721e2 Mon Sep 17 00:00:00 2001 From: timyhac Date: Sun, 2 Oct 2022 15:05:37 +1100 Subject: [PATCH 5/7] More work on the implementation. The main issue now is how to suport Try pattern and async. Currently using a tuple return value --- src/libplctag/ITag.cs | 8 +++ src/libplctag/NativeTagWrapper.cs | 30 ++++---- src/libplctag/Tag.cs | 52 ++++++++++++++ src/libplctag/TagOfT.cs | 109 ++++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+), 17 deletions(-) diff --git a/src/libplctag/ITag.cs b/src/libplctag/ITag.cs index 2c1684b2..9c687827 100644 --- a/src/libplctag/ITag.cs +++ b/src/libplctag/ITag.cs @@ -23,10 +23,18 @@ public interface ITag : IDisposable Status GetStatus(); void Initialize(); Task InitializeAsync(CancellationToken token = default); + bool TryInitialize(); + Task TryInitializeAsync(CancellationToken token = default); + object Read(); Task ReadAsync(CancellationToken token = default); + (bool isStatusOk, object value) TryRead(); + Task<(bool isStatusOk, object value)> TryReadAsync(CancellationToken token = default); + void Write(); Task WriteAsync(CancellationToken token = default); + bool TryWrite(); + Task TryWriteAsync(CancellationToken token = default); Object Value { get; set; } } diff --git a/src/libplctag/NativeTagWrapper.cs b/src/libplctag/NativeTagWrapper.cs index fa5b2084..05a219af 100644 --- a/src/libplctag/NativeTagWrapper.cs +++ b/src/libplctag/NativeTagWrapper.cs @@ -320,7 +320,6 @@ public async Task WriteAsync(CancellationToken token = default) ThrowIfStatusNotOk(status); } - public Status TryInitialize() { ThrowIfAlreadyDisposed(); @@ -378,14 +377,15 @@ public async Task TryInitializeAsync(CancellationToken token = default) SetUpEvents(); - await readTask.Task; + var status = await readTask.Task; _isInitialized = true; - return readTask.Task.Result; + return status; } } } + public Status TryRead() { ThrowIfAlreadyDisposed(); @@ -393,9 +393,9 @@ public Status TryRead() var millisecondTimeout = (int)Timeout.TotalMilliseconds; - var result = (Status)_native.plc_tag_read(nativeTagHandle, millisecondTimeout); - - return result; + var status = (Status)_native.plc_tag_read(nativeTagHandle, millisecondTimeout); + + return status; } public async Task TryReadAsync(CancellationToken token = default) @@ -424,11 +424,12 @@ public async Task TryReadAsync(CancellationToken token = default) var readTask = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); readTasks.Push(readTask); _native.plc_tag_read(nativeTagHandle, TIMEOUT_VALUE_THAT_INDICATES_ASYNC_OPERATION); - await readTask.Task; - return readTask.Task.Result; + var status = await readTask.Task; + return status; } } } + public Status TryWrite() { ThrowIfAlreadyDisposed(); @@ -436,8 +437,8 @@ public Status TryWrite() var millisecondTimeout = (int)Timeout.TotalMilliseconds; - var result = (Status)_native.plc_tag_write(nativeTagHandle, millisecondTimeout); - return result; + var status = (Status)_native.plc_tag_write(nativeTagHandle, millisecondTimeout); + return status; } public async Task TryWriteAsync(CancellationToken token = default) @@ -466,8 +467,8 @@ public async Task TryWriteAsync(CancellationToken token = default) var writeTask = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); writeTasks.Push(writeTask); _native.plc_tag_write(nativeTagHandle, TIMEOUT_VALUE_THAT_INDICATES_ASYNC_OPERATION); - await writeTask.Task; - return writeTask.Task.Result; + var status = await writeTask.Task; + return status; } } } @@ -630,8 +631,6 @@ private void ThrowIfStatusNotOk(Status? status = null) throw new LibPlcTagException(statusToCheck); } - - private void SetNativeTagValue(Func nativeMethod, int offset, T value) { ThrowIfAlreadyDisposed(); @@ -719,9 +718,6 @@ string FormatPlcType(PlcType? type) } - - - void SetUpEvents() { diff --git a/src/libplctag/Tag.cs b/src/libplctag/Tag.cs index 97a162b3..c1489794 100644 --- a/src/libplctag/Tag.cs +++ b/src/libplctag/Tag.cs @@ -298,6 +298,7 @@ public uint? StringTotalLength /// Can only be called once per instance. /// Timeout is controlled via class property. /// + /// public void Initialize() => _tag.Initialize(); /// @@ -355,6 +356,55 @@ public uint? StringTotalLength /// public Task WriteAsync(CancellationToken token = default) => _tag.WriteAsync(token); + /// + /// Creates the underlying data structures and references required before tag operations. + /// + /// + /// + /// Whether the operation was successful. + /// + /// + /// + /// Initializes the tag by establishing necessary connections. + /// Can only be called once per instance. + /// Timeout is controlled via class property. + /// + public bool TryInitialize() + { + var status = _tag.TryInitialize(); + return _tag.IsStatusOk(status); + } + + public async Task TryInitializeAsync(CancellationToken token = default) + { + var status = await _tag.TryInitializeAsync(token); + return _tag.IsStatusOk(status); + } + + public bool TryRead() + { + var status = _tag.TryRead(); + return _tag.IsStatusOk(status); + } + + public async Task TryReadAsync(CancellationToken token = default) + { + var status = await _tag.TryReadAsync(token); + return _tag.IsStatusOk(status); + } + + public bool TryWrite() + { + var status = _tag.TryWrite(); + return _tag.IsStatusOk(status); + } + + public async Task TryWriteAsync(CancellationToken token = default) + { + var status = await _tag.TryWriteAsync(token); + return _tag.IsStatusOk(status); + } + public void Abort() => _tag.Abort(); public void Dispose() => _tag.Dispose(); @@ -371,6 +421,8 @@ public uint? StringTotalLength /// Tag's current status public Status GetStatus() => _tag.GetStatus(); + public bool IsStatusOk(Status status) => _tag.IsStatusOk(status); + public bool GetBit(int offset) => _tag.GetBit(offset); public void SetBit(int offset, bool value) => _tag.SetBit(offset, value); diff --git a/src/libplctag/TagOfT.cs b/src/libplctag/TagOfT.cs index c72e3efa..55013fe5 100644 --- a/src/libplctag/TagOfT.cs +++ b/src/libplctag/TagOfT.cs @@ -185,6 +185,115 @@ public void Write(T value) Write(); } + /// + public bool TryInitialize() + { + var isStatusOk = _tag.TryInitialize(); + if(!isStatusOk) + { + return false; + } + else + { + DecodeAll(); + return true; + } + } + + /// + public async Task TryInitializeAsync(CancellationToken token = default) + { + var isStatusOk = await _tag.TryInitializeAsync(token); + if (!isStatusOk) + { + return false; + } + else + { + DecodeAll(); + return true; + } + } + + /// + public async Task<(bool isStausOk, T value)> TryReadAsync(CancellationToken token = default) + { + var isStatusOk = await _tag.TryReadAsync(token); + if(!isStatusOk) + { + return (false, default(T)); + } + else + { + DecodeAll(); + return (true, Value); + } + } + + /// + public (bool isStatusOk, T value) TryRead() + { + var isStatusOk = _tag.TryRead(); + if(!isStatusOk) + { + return (false, default(T)); + } + else + { + DecodeAll(); + return (true, Value); + } + } + + (bool isStatusOk, object value) ITag.TryRead() => TryRead(); + + async Task<(bool isStatusOk, object value)> ITag.TryReadAsync(CancellationToken token) => await TryReadAsync(token); + + /// + public async Task TryWriteAsync(CancellationToken token = default) + { + if (!_tag.IsInitialized) + { + if (!(await _tag.TryInitializeAsync(token))) + { + return false; + } + } + + EncodeAll(); + + return await _tag.TryWriteAsync(token); + } + + /// + public async Task TryWriteAsync(T value, CancellationToken token = default) + { + Value = value; + return await TryWriteAsync(token); + } + + /// + public bool TryWrite() + { + if (!_tag.IsInitialized) + { + if (!_tag.TryInitialize()) + { + return false; + } + } + + EncodeAll(); + return _tag.TryWrite(); + } + + /// + public bool TryWrite(T value) + { + Value = value; + return TryWrite(); + } + void DecodeAll() { Value = _plcMapper.Decode(_tag); From 802245a4c888b25e4723778a219354059b121ac6 Mon Sep 17 00:00:00 2001 From: timyhac Date: Sun, 2 Oct 2022 17:15:08 +1100 Subject: [PATCH 6/7] Made the signature of TryRead and TryReadAsync only return bool and Task instead of the tuple with that and the Value. --- src/libplctag/ITag.cs | 4 ++-- src/libplctag/TagOfT.cs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libplctag/ITag.cs b/src/libplctag/ITag.cs index 9c687827..2748a593 100644 --- a/src/libplctag/ITag.cs +++ b/src/libplctag/ITag.cs @@ -28,8 +28,8 @@ public interface ITag : IDisposable object Read(); Task ReadAsync(CancellationToken token = default); - (bool isStatusOk, object value) TryRead(); - Task<(bool isStatusOk, object value)> TryReadAsync(CancellationToken token = default); + bool TryRead(); + Task TryReadAsync(CancellationToken token = default); void Write(); Task WriteAsync(CancellationToken token = default); diff --git a/src/libplctag/TagOfT.cs b/src/libplctag/TagOfT.cs index 55013fe5..78c6c3bd 100644 --- a/src/libplctag/TagOfT.cs +++ b/src/libplctag/TagOfT.cs @@ -216,38 +216,38 @@ public async Task TryInitializeAsync(CancellationToken token = default) } /// - public async Task<(bool isStausOk, T value)> TryReadAsync(CancellationToken token = default) + public async Task TryReadAsync(CancellationToken token = default) { var isStatusOk = await _tag.TryReadAsync(token); if(!isStatusOk) { - return (false, default(T)); + return false; } else { DecodeAll(); - return (true, Value); + return true; } } /// - public (bool isStatusOk, T value) TryRead() + public bool TryRead() { var isStatusOk = _tag.TryRead(); if(!isStatusOk) { - return (false, default(T)); + return false; } else { DecodeAll(); - return (true, Value); + return true; } } - (bool isStatusOk, object value) ITag.TryRead() => TryRead(); + bool ITag.TryRead() => TryRead(); - async Task<(bool isStatusOk, object value)> ITag.TryReadAsync(CancellationToken token) => await TryReadAsync(token); + async Task ITag.TryReadAsync(CancellationToken token) => await TryReadAsync(token); /// public async Task TryWriteAsync(CancellationToken token = default) From 4d7c2a2d101ca0887a7fe4deca5056dc7147b43c Mon Sep 17 00:00:00 2001 From: timyhac Date: Sun, 2 Oct 2022 20:41:27 +1100 Subject: [PATCH 7/7] Revert version change --- src/Examples/VB.NET DotNetCore/VB.NET DotNetCore.vbproj | 2 +- .../libplctag.NativeImport.Benchmarks.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Examples/VB.NET DotNetCore/VB.NET DotNetCore.vbproj b/src/Examples/VB.NET DotNetCore/VB.NET DotNetCore.vbproj index 2f9bbe21..e824a0d4 100644 --- a/src/Examples/VB.NET DotNetCore/VB.NET DotNetCore.vbproj +++ b/src/Examples/VB.NET DotNetCore/VB.NET DotNetCore.vbproj @@ -3,7 +3,7 @@ Exe VB.NET_DotNetCore - net6.0 + netcoreapp3.1 diff --git a/src/libplctag.NativeImport.Benchmarks/libplctag.NativeImport.Benchmarks.csproj b/src/libplctag.NativeImport.Benchmarks/libplctag.NativeImport.Benchmarks.csproj index f97a3d81..2eb796ff 100644 --- a/src/libplctag.NativeImport.Benchmarks/libplctag.NativeImport.Benchmarks.csproj +++ b/src/libplctag.NativeImport.Benchmarks/libplctag.NativeImport.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + netcoreapp3.1