是否等待所有异步

是否等待所有异步

本文介绍了Nhibernate CommitAsync 是否等待所有异步 CRUD 操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚 nhibernate 中的 CommitAsync 方法如何与 SaveAsyncUpdateAsync 和 & 结合使用.DeleteAsync

I'm trying to figure out how the CommitAsync method in nhibernate works in conjunction with SaveAsync, UpdateAsync, & DeleteAsync

我的问题是:假设我多次调用 SaveAsyncUpdateAsync 而不等待它们.稍后我调用 CommitAsync.CommitAsync 是否会等待对 SaveAsyncUpdateAsync 的所有调用完成?或者我必须在调用 CommitAsync 之前等待它们?

My question is: say i call SaveAsync, or UpdateAsync multiple times without awaiting them. Then sometime later I call CommitAsync. Will CommitAsync wait for all of the calls to SaveAsync and UpdateAsync to finish? Or do i have to await them before calling CommitAsync?

我创建了下面的测试并尝试在不等待的情况下保存多个用户,然后尝试使用 CommitAsync 提交以查看数据库中是否会丢失任何内容或计数是否会关闭,但似乎工作.但是,我在网上看到的每个示例都在提交之前等待所有异步 CRUD 操作.

I Created the test below and tried saving multiple users without awaiting them then tried to commit using CommitAsync to see if any would be missing from the DB or if the count would be off but it seems to work. However, every example I've seen online awaits all of their async CRUD operations before committing.

[TestFixture]
public class AsyncTests
{
    [Test]
    public async Task TestAsync()
    {
        var sessionSource = new SessionSource();
        int saveCount = 100000;
        using (var session = sessionSource.CreateSession())
        {
            using (var t = session.BeginTransaction())
            {
                SaveMany(saveCount, session);
                await t.CommitAsync();
            }
        }

        int count = 0;
        using (var sessoin = sessionSource.CreateSession())
        {
            count = sessoin.Query<User>().Count();
        }

        Assert.That(count, Is.EqualTo(saveCount));
    }

    public void SaveMany(int count, ISession session)
    {
        for (var i = 0; i < count; i++)
        {
            Save(session);
        }
    }

    private Task<object> Save(ISession session)
    {
        return session.SaveAsync(new User()
        {
            Guid = Guid.NewGuid(),
            FirstName = "saveasync",
            MiddleName = "middle",
            LastName = "last"
        });
    }
}

推荐答案

基于这篇文章:NHibernate 5:异步 IO 绑定操作支持
您应该等待所有 async 方法.

Based on this article: NHibernate 5: async IO bound operations support
you should await all of the async methods.

这里我复制相关部分:
请注意,此功能不适用于并行,仅用于非并行异步,因此请确保在发出新调用之前await 每次调用使用同一个会话.

Here I copy the relevant part:
Note that this feature is not intended for parallelism, only non-parallel asynchrony, so make sure to await each call before issuing a new call using the same session.

换句话说,不要这样做:

In other words, don’t do this:

Task<Customer> task1 = session.GetAsync<Customer>(1);
Task<Customer> task2 = session.GetAsync<Customer>(2);

Customer[] customers = await Task.WhenAll(task1, task2);

改为这样做:

Customer customer1 = await session.GetAsync<Customer>(1);
Customer customer2 = await session.GetAsync<Customer>(2);

关于并行与异步的简要说明.并行执行是异步执行的一个子集:每个并行执行都是异步的,但并非每个异步执行都是并行的.

A quick side note about parallelism versus asynchrony. Parallel execution is a subset of asynchronous execution: every parallel execution is asynchronous, but not every asynchronous execution is parallel.

异步执行某事对应于不阻塞调用者".它可以通过立即开始这项工作来实现,这意味着它将并行完成,或者等待调用者完成他们的工作,这意味着工作将按顺序执行,由同一个线程或另一个线程执行.无论哪种方式,作业都不会阻塞调用者,因此我们可以说它将异步执行.

Executing something asynchronously corresponds to "without blocking the caller". It can be achieved by starting this work immediately, which means it will be done in parallel, or by waiting until the caller is finished with their stuff, which means the work will be executed sequentially, either by the same or another thread. Either way, the job will not block the caller and thus we can say that it will be executed asynchronously.

这篇关于Nhibernate CommitAsync 是否等待所有异步 CRUD 操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 23:19