Async Functionality
Asynchronous Programming Support
An async version of the API designed to support asynchronous programming (async/await) is available in the nsoftware.async.IPWorksOpenPGP namespace. Both the default (sync) and the async APIs are present in the same library located in the installation directory at lib\net6.0\nsoftware.IPWorksOpenPGP.dll.
The async version of the API is designed to support asynchronous programming (async/await) for all operations. In addition, the async API delivers performance improvements for these operations compared to the default version of the API. In Visual Studio's intellisense you will see methods which are awaitable and return a System.Threading.Tasks.Task object.
The async/await pattern provides a simple way to write sequential code that is easy to understand but also takes advantage of the inherent benefits of asynchronous programming. A common example of this is awaiting an asynchronous task which will wait for the operation to complete but also ensure the UI of an application is responsive and does not appear frozen.
All versions of the API use non-blocking sockets internally, the async functionality provided in this version of the API is related only to the .NET asynchronous programming model.
Cross-Platform Development
The async API can be used for cross-platform development and supports .NET 6.0 and up. Refer to the cross-platform async sample projects included with the toolkit for more detailed examples.
Error Handling
Exceptions can be handled using try/catch when awaiting a method. The behavior when using await is the same as when handling exceptions in the synchronous version of the API. There are no special requirements and the exception will contain the same Code and Message property values as the other versions of this library.
If the await keyword is not used, then the exception can be obtained from the task's Exception.InnerException property.
InvokeThrough
The InvokeThrough property is an optional property which specifies a SynchronizationContext to be used when firing events. When set, the component will fire events within the specified context. A common use case is updating Windows Forms UI elements from within an event of the component. In order to ensure that the UI update does not result in an invalid cross-thread operation set InvokeThrough to a valid value. For instance:
component.InvokeThrough = WindowsFormsSynchronizationContext.Current;
This property is applicable in any project type and may be set to any valid SynchronizationContext such as System.Threading.SynchronizationContext.Current.
The default value is null and no synchronization context will be used.
Note: Use of this property can impact performance and should only be used when necessary.
Concurrency Notes
While the asynchronous methods of the components do return a Task object only one operation can be in progress at any given time. There is no locking mechanism and it is generally considered to be dangerous to create two active tasks which use the same component instance. If multiple concurrent operations are required then multiple component instances should be used.