Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果没有要完成的任务,Task.WhenAll将挂起_C#_Mongodb_Asynchronous - Fatal编程技术网

C# 如果没有要完成的任务,Task.WhenAll将挂起

C# 如果没有要完成的任务,Task.WhenAll将挂起,c#,mongodb,asynchronous,C#,Mongodb,Asynchronous,我有一个将对象列表插入MongoDB的方法 public class StorageService : IStorageService { public Task<BulkWriteResult<Option>> SaveOptions(List<Option> contracts) { var context = new MongoContext<Option>(); return context.SaveCollecti

我有一个将对象列表插入MongoDB的方法

public class StorageService : IStorageService
{
  public Task<BulkWriteResult<Option>> SaveOptions(List<Option> contracts)
  {
    var context = new MongoContext<Option>();
    return context.SaveCollection(contracts);
  }
}

var optionIds = Task
  .WhenAll(storageService.SaveOptions(optionDetails.Values.ToList()))
  .Result;

所以,响应取决于3.3,3.3取决于3.2,3.2取决于3.1。如果你知道如何把它变成一个非阻塞呼叫,我洗耳恭听。目前,我认为一个HTTP请求中的三个阻塞调用比三个单独的异步HTTP请求要好。

无法详细解释,但问题似乎是由.NET framework和Mongo DB驱动程序之间的不兼容引起的。目前我使用的是.NET4.6.1和Mongo2.6.1,运行良好

昨天,任何将空对象列表保存到Mongo DB的尝试都会导致死锁

然后我尝试重构代码并安装最新版本的Mongo DB,即2.7.0。现在,任何使用Mongo DB的CRUD操作都会返回此错误。没有调用堆栈和有关此异常的更多详细信息

MethodAccessException: Attempt by method 'MongoDB.Driver.ClientSession..ctor(MongoDB.Driver.IMongoClient, MongoDB.Driver.ClientSessionOptions, MongoDB.Driver.IServerSession, Boolean)' to access method 'MongoDB.Driver.Core.Clusters.ClusterClock..ctor()' failed.
然后我尝试将Mongo DB的版本降低到2.6.1,当我尝试插入空的对象列表时,我得到了这个异常,这是正确的。当我插入至少一条记录时,它会按预期工作

System.AggregateException: 'One or more errors occurred.'
ArgumentException: Must contain at least 1 request.
Parameter name: requests
测试代码

var item = new Demo
{
  Symbol = "SomeSymbol",
  Expiration = "2019-01-01"
};

var list = new List<Demo>();

list.Add(item); 
list.Add(item); // if I comment these lines, then Mongo 2.6.1 returns correct exception

var optionIds = Task.WhenAll(storageService.Save(list)).Result;
var项=新演示
{
Symbol=“SomeSymbol”,
到期日=“2019-01-01”
};
var list=新列表();
列表。添加(项目);
列表。添加(项目);//如果我对这些行进行注释,那么Mongo2.6.1将返回正确的异常
var optionIds=Task.WhenAll(storageService.Save(list)).Result;
Save方法作为

公共任务存储集合(列表项)
{
var记录=新列表();
var进程=新列表();
items.ForEach(合同=>
{
var记录=新的ReplaceOneModel(生成器)
.过滤器
.其中(o=>o.Id==contract.Id),contract)
{
IsUpsert=true
};
记录。添加(记录);
});
返回集合。BulkWriteAsync(记录);
}

这里的一个快速测试表明,
任务。实际上,当没有任何任务传入时,
不会暂停<代码>var nothingToDo=新列表();任务。WhenAll(nothingToDo);控制台。写入线(“全部完成”)-所以。。。这里可能有一个错误的假设。此外,您几乎不应该使用
.Result
.Wait()
,而且这种情况肯定比“几乎”更倾向于“从不”一方,即您只有一个任务,而不管是否没有、一个或多个合同,所以您甚至不需要wheall。也就是说,就像Marc Gravell提到的,不要使用Result或Wait,如果需要等待任务/获取其结果,则使用Wait。optionIds在什么框架下运行?
optionIds
这个方法应该从多个API收集数据,所以我需要获取此调用的结果,我看不到任何替代结果。ASP.NET Web API针对异步代码进行了优化。为什么
下载选项
不是
异步任务下载选项
?你不应该像那样用
Result
阻塞线程。更重要的是,您不应该创建一个
任务
,它的唯一目的是等待另一个
任务
。充其量(读取,最坏)应该是
storageService.SaveOptions(optionDetails.Values.ToList()).Result
。但是您实际上应该只使用
wait-storageService.SaveOptions(optionDetails.Values.ToList())
MethodAccessException: Attempt by method 'MongoDB.Driver.ClientSession..ctor(MongoDB.Driver.IMongoClient, MongoDB.Driver.ClientSessionOptions, MongoDB.Driver.IServerSession, Boolean)' to access method 'MongoDB.Driver.Core.Clusters.ClusterClock..ctor()' failed.
System.AggregateException: 'One or more errors occurred.'
ArgumentException: Must contain at least 1 request.
Parameter name: requests
var item = new Demo
{
  Symbol = "SomeSymbol",
  Expiration = "2019-01-01"
};

var list = new List<Demo>();

list.Add(item); 
list.Add(item); // if I comment these lines, then Mongo 2.6.1 returns correct exception

var optionIds = Task.WhenAll(storageService.Save(list)).Result;
public Task<BulkWriteResult<T>> SaveCollection(List<T> items)
{
  var records = new List<ReplaceOneModel<T>>();
  var processes = new List<Task<ReplaceOneResult>>();

  items.ForEach(contract =>
  {
    var record = new ReplaceOneModel<T>(Builders<T>
      .Filter
      .Where(o => o.Id == contract.Id), contract)
    {
      IsUpsert = true
    };

    records.Add(record);
  });

  return Collection.BulkWriteAsync(records);
}