Current filter:
                                You should refresh the page.
                                  • Q: How do I get started with asynchronous operations in general and their XPO use in particular?
                                    A:  Check out the Asynchronous Programming Patterns and Task-based Asynchronous Pattern articles in Microsoft .NET Guide. To get started with XPO asynchronous APIs specifically, consider the following resources:
                                     - see the XPO - Async/Await Method Support (v18.2)  blog post;
                                     - download our GitHub demo;
                                     - review our XpoTutorials demo files ("c:\Users\Public\Documents\DevExpress Demos 18.2\Components\WinForms\CS\XpoTutorials\AsyncLoadingTaskBased\AsyncLoadingTaskBased.cs" );
                                     - consult with the SessionXPQueryExtensions, and other key API references.

                                    Q:  Do all ADO.NET providers support async operations and how XPO deals with it?
                                    A:  Not all ADO.NET providers supported by XPO support asynchronous operations. Also, even though XPO can pass System.Threading.CancellationToken from XPO async APIs to the underlying ADO.NET provider APIs, certain providers can ignore this token. To force XPO to always wrap synchronous methods in Task.Run calls, you can set the static XpoDefault.DataStoreAsyncBehavior property to WrapAlways. This can be used in desktop apps to create a non-blocking pseudo-asynchronous UI for providers like Oracle that do not natively implement async methods yet. Do not use this approach in Web apps.

                                    Q:  Do these new Task-based APIs support cancellation?
                                    A:  All XPO methods accept System.Threading.CancellationToken. For more information on how to cancel async operations with XPO, refer to the attached XpoAsyncCancel.zip project (research its Form1.cs file).

                                    Q:  Do these new Task-based APIs provide progress notifications?
                                    A:  We do not provide any means for reporting progress by the following reasons:
                                     - Standard asynchronous APIs (IDbConnection, IDbCommand, IDataReader, etc.) of ADO.NET drivers supported by XPO do not support IProgress or similar means.
                                     - Even if we had provided XPO method overloads accepting the IProgress parameters, it would not be much usable: the progress would stay at 0% most of the method execution time and then immediately go to 100%. For instance, 0%...0%...0%...0%...0%...99%...100%. That is because the most heavy operations are done at the database level and their progress could not be reliably determined.

                                    Q: Can I use async/await with  direct SQL queries (Session methods like ExecuteScalar, ExecuteQuery, GetObjectsFromQuery, etc.)?
                                    A:  Yes, this is supported in v19.1+. Also, note that not all ADO.NET providers supported by XPO support asynchronous operations.
                                    In v18.2, wrap these method calls into the Task.Run method manually, if required. Note that the asynchronous operation cannot be canceled under this approach.

                                    Q:  Can I use async/await with XPCollection and XPView?
                                    A:  No, XPCollection.LoadAsync and XPView.LoadAsync will not return Task and thus will not support async/await. We recommend that you use XPQuery  instead - it is a more efficient way to query data.

                                    Q: Should we use the ThreadSafeDataLayer to use async/await XPO methods?
                                    A: In general, the requirement to use the ThreadSafeDataLayer remains the same as if synchronous operations were used in the same context. If the existing code works with the SimpleDataLayer and you just change it to use asynchronous methods, you can continue using the SimpleDataLayer.
                                    The only thing that should be avoided is the parallel execution of two asynchronous operations in the context of one Session instance. Use the await operator if you need to call an asynchronous method several times.

                                    [C#]
                                    await session.DoSomethingAsync(); await session.DoSomethingAsync();

                                    Q:  Are there any plans to extend XAF's IObjectSpace to support async/await?
                                    A:  UPDATE for XAF v19.2: Refer to the How to perform asynchronous operations in XAF WinForms apps using the IObjectSpaceAsync interface KB article for a solution.


                                    While we cannot provide any ETA, this XPO feature is definitely the first step in this direction. This support will bring XAF users the following benefits:
                                     - improve XAF WinForms UX and perceived performance with the help of asynchronous Actions (open DetailView from ListView, save DetailView, execute long custom Actions);
                                     - improve the new ASP.NET Core Data Service throughput under a high load.
                                    For more information on this feature, please refer to the following support tickets: T112329AS6060CQ59274Q352118.

                                    Right away, you can use the IObjectSpace > GetObjectsQuery  method with ToListAsync, ToArrayAsync, CountAsync and other suitable IQueryable methods. Create, update and delete operations require us to extend IObjectSpace and then support these XXXAsync methods at the UI level. However, nothing prevents you from wrapping these IObjectSpace method calls into the Task.Run method manually, if required. Note that the asynchronous operation cannot be canceled under this approach.

                                Show all comments
                                • Dusan Pupis 03.20.2019

                                  I'm having a bit of a problem.
                                  I'm using WCF, and connection pooling, and SQL server depen dency notifications (and SQL provider descendant for CTE support).
                                  Basically, everything available :)

                                  Connection is made thus (DbSqlServerProvider is the name of MSSqlProvider descendant with CTE):

                                  [C#]
                                  public override IDataStore CreateDataStore(ConnectionInfo ci) { DbSqlServerProvider.Register(); var xpoConnectionString = ci.User.IsBlank() ? DbSqlServerProvider.GetConnectionString(ci.Server, ci.Database) : DbSqlServerProvider.GetConnectionString(ci.Server, ci.User, ci.Password, ci.Database); xpoConnectionString = String.Concat(xpoConnectionString, ";", "MultipleActiveResultSets=true"); var sqlParser = new ConnectionStringParser(xpoConnectionString); sqlParser.RemovePartByName(DbSqlServerProvider.XpoProviderTypeParameterName); var sqlConnectionString = sqlParser.GetConnectionString(); var sqlConnection = new SqlConnection(sqlConnectionString); var sqlStore = new DbSqlServerProvider(sqlConnection, AutoCreateOption.DatabaseAndSchema); DbEngine.FSPath = SqlClrAssembly.Check(sqlConnection); var poolConnectionString = XpoDefault.GetConnectionPoolString(xpoConnectionString); var poolStore = XpoDefault.GetConnectionProvider(poolConnectionString, AutoCreateOption.DatabaseAndSchema); var cacheConfiguration = new DataCacheConfiguration(DataCacheConfigurationCaching.NotInList); var objectsToDispose = new IDisposable[] { sqlConnection }; var root = MSSql2005SqlDependencyCacheRoot.CreateSqlDependencyCacheRoot(poolStore, sqlConnection, sqlStore, cacheConfiguration, out objectsToDispose); var node = new DataCacheNodeLocal(root) { MaxCacheLatency = TimeSpan.Zero }; node.ProcessCookie(DataCacheCookie.Empty); return node; }

                                  So far, so good ...
                                  On the client, on the other side of the WCF code is:

                                  [C#]
                                  public override IDataStore CreateDataStore(ConnectionInfo ci) ... var client = new CachedDataStoreClient(binding, new EndpointAddress(uri)); ... var root = client as ICachedDataStore; var node = new DataCacheNode(root) { ... }; ... node.ProcessCookie(DataCacheCookie.Empty); return node; }

                                  Actually, above is wrapped in 'XDataStoreWrapper' which just wrappes above node as IDataStore and adds some logging.

                                  This worked until 19.1.
                                  Now, under certain circumstances, I get the exception:

                                  Your 'XDataStoreWrapper' Connection Provider does not support the 'DevExpress.Xpo.DB.IDataStoreAsync' interface. Please implement this interface, or use another compatible Connection Provider.

                                  Now, I *cannot* forward implementation of IDataStoreAsync in wrapper as DataCacheNode (nor ICachedDataStore) do NOT implement it. So I basically wrote the following dummy wrappers:

                                  [C#]
                                  public sealed class XDataStoreWrapper : IDataStore, IDataStoreSchemaExplorer, ICommandChannel, ICachedDataStore, ICacheToCacheCommunicationCore, IDataStoreAsync, ... ... public IDataStore Store { get; } public XDataStoreWrapper(IDataStore nested) => Store = nested; ... ... public Task<ModificationResult> ModifyDataAsync(CancellationToken token, params ModificationStatement[] statements) => Store is IDataStoreAsync sa ? sa.ModifyDataAsync(token, statements) : Task.Factory.StartNew(() => Store.ModifyData(statements), token); public Task<SelectedData> SelectDataAsync(CancellationToken token, params SelectStatement[] statements) => Store is IDataStoreAsync sa ? sa.SelectDataAsync(token, statements) : Task.Factory.StartNew(() => Store.SelectData(statements), token); ... ...

                                  ... but it doesn't feel quite right.

                                  Basically what I'm asking is since you provide class CachedDataStoreService (which implements ICachedDataStoreService), shouldn't there also be (say) CachedDataStoreServiceAsync implementing ICachedDataStoreServiceAsync.

                                  Or am I missing something obvious?

                                • Dusan Pupis 03.20.2019

                                  Actually, it seems I'm overcomplicating it.
                                  Basically, I try to avoid the exception:

                                  Connection Provider does not support the 'DevExpress.Xpo.DB.IDataStoreAsync' interface. Please implement this interface, or use another compatible Connection Provider.

                                  So, I change this

                                  [C#]
                                  var client = new CachedDataStoreClient(binding, new EndpointAddress(uri)); var node = new DataCacheNode(client); return node;

                                  ... to this ...

                                  [C#]
                                  var client = new CachedDataStoreClientAsync(binding, new EndpointAddress(uri)); var node = new DataCacheNode(client); return node;

                                  But that doesn't seem to help, as ICachedDataStoreAsync which client implements is 'lost' when chaining to DataCacheNode?

                                • Dusan Pupis 03.20.2019

                                  So, is there something like DataCacheNodeAsync planned for 19.1 or should fallback to Task.Run substitues in IDataStore wrapper classes via Task.Factory.Start as above in the first post?

                                • Dennis (DevExpress Support) 03.20.2019

                                  @Dusan Pupis: Thank you for testing our preview build! We will answer you in a separate ticket created on your behalf:
                                  Trying to avoid the exception: Connection Provider does not support the 'DevExpress.Xpo.DB.IDataStoreAsync' interface. in v19.1 CTP.

                                • Christoph Weinzierl-Heigl [msg] 05.06.2019

                                  >> Q:  Can I use async/await with XPCollection and XPView?
                                  >> A:  No, XPCollection.LoadAsync and XPView.LoadAsync will not return Task and thus will not support async/await. We recommend that you use XPQuery  instead - it is a more efficient way to query data.

                                  I have remark regarding this answer. Actually, one can implement their own Extension methods based on the TaskCompletionSource to make XPCollection.LoadAsync und XPView.LoadAsync awaitable. There is a nice, albeit old answer from Manuel Grundner in Q555310 explaining this. I have been using my own extension methods for a long time now and they work sufficiently well. Here is an example of the XPCollection.LoadAsync using TaskCompletionSource:

                                  [C#]
                                  /// <summary> /// Asynchronously loads persistent objects of a specific type from the data store into the collection, and returns an awaitable Task. /// </summary> /// <param name="collection">The instance on which this extension method is executed.</param> /// <returns>An awaitable Task whose result holds the collection's contents.</returns> public static Task<ICollection> LoadCollectionAsync(this XPBaseCollection collection) { var tcs = new TaskCompletionSource<ICollection>(); AsyncLoadObjectsCallback h = null; h = (result, exception) => { h = null; if (exception != null) tcs.SetException(exception); else if (result.Length > 0) tcs.SetResult(result[0]); else tcs.SetResult(null); }; if (!collection.IsLoaded && collection.LoadAsync(h)) return tcs.Task; return Task.Factory.StartNew(() => (ICollection) collection); }
                                • Dennis (DevExpress Support) 05.06.2019

                                  @Christoph: We considered this approach, but eventually declined it, because the caller thread must have SynchronizationContext. For instance, your approach will not work in Console or ASP.NET Core apps. It will still work in WinForms,  WPF or UWP apps. The Task-based solution we provided does not require SynchronizationContext and will work with any apps. For more information, refer to the following public community resources:
                                  https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html
                                  https://devblogs.microsoft.com/pfxteam/await-synchronizationcontext-and-console-apps/

                                0 Solutions

                                Creation Date Importance Sort by