【问题标题】:Task Behaviour in a process进程中的任务行为
【发布时间】:2019-09-21 09:28:31
【问题描述】:

我的代码实际上没有问题,但我可能会遇到性能问题。

根据我对任务的了解,首先启动的任务说 TaskA 可以与另一个任务说 TaskB 并行运行,但 TaskB 可能会在 TaskA 完成其工作之前完成并退出其线程。所以在我的代码中,我试图继续操作,但首先要知道任务状态。我的代码中名为TaskResult 的任务是否会在前面的代码行运行之前完成,或者如果我想要的话,我应该在上面使用Task.Wait() 吗?

 public virtual async Task<OperationResult> DeleteAsync(Expression<Func<TEntity, bool>> expression)
        {
            Task TaskResult = await _DbContext.Set<TEntity>().RemoveRange(IEnumerable<TEntity>);
            if (TaskResult.Status == TaskStatus.RanToCompletion)
            {
                return new OperationResult()
                {
                    Message = "",
                    ReturnObject = null,
                    Status = OperationStatus.Deleted,
                    Succeeded = true
                };
            }
            if (TaskResult.Status == TaskStatus.Faulted)
            {
                return new OperationResult()
                {
                    Message = "",
                    ReturnObject = null,
                    Status = OperationStatus.UnknownError,
                    Succeeded = false
                };
            }

        }

【问题讨论】:

    标签: c# asp.net-core task


    【解决方案1】:

    await 关键字将停止执行您的方法,直到 Task 完成。一旦完成,await 将返回Task 的结果,或者抛出Task 内部发生的异常(如果有的话)。因此,如果您已经在等待 Task 是否发生故障,则没有必要测试它,因为如果它发生故障,await 会抛出异常。

    只需将其包装在 try/catch 块中即可。

    但是您的代码甚至无法编译,因为:

    1. DbSet&lt;T&gt;.RemoveRange 不返回 Task 因为它实际上根本不与数据库对话。它只是删除内存中的记录。您需要致电 DbContext.SaveChangesAsync() 以提交您的更改。
    2. 您实际上并未将对象列表传递给RemoveRange。 (您是否更改了此示例的代码?)
    3. 一旦等待 Taskawait 关键字将返回 Task 的结果,而不是 Task 本身。

    下面是一个示例,说明如何编写:

    public virtual async Task<OperationResult> DeleteAsync(Expression<Func<TEntity, bool>> expression) {
    
        _DbContext.Set<TEntity>().RemoveRange(somethinghere);
    
        try {
            //commit the changes
            var result = await _DbContext.SaveChangesAsync();
    
            //result will be an int (the number of records changed), not a Task
    
            //if we got this far, we succeeded
            return new OperationResult()
            {
                Message = "",
                ReturnObject = null,
                Status = OperationStatus.Deleted,
                Succeeded = true
            };
        } catch (Exception e) {
    
            return new OperationResult()
            {
                Message = "", //you can use e.Message here if you want
                ReturnObject = null,
                Status = OperationStatus.UnknownError,
                Succeeded = false
            };
        }
    }
    

    请注意,您可以只输入:

    await _DbContext.SaveChangesAsync();
    

    如果您不打算使用result

    【讨论】:

    • 非常感谢您的澄清。将对象传递给 RemoveRange() 是一个印刷错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    • 2018-01-10
    相关资源
    最近更新 更多