C#访问MongoDB进行读操作时,为什么异步读比同步读要慢很多呢?
请教各位大神,我在使用C#对MongoDB模拟大并发读的时候,使用异步发起500次读的请求,耗时7秒;但使用同步发起500次读的请求,只耗时600多毫秒。有大神知道大概是什么原因吗?
MongDb的服务器版本是3.4,C#的驱动是2.4.4版本的mongocsharpdriver。
数据访问类:
public class Dal
{
private IMongoClient client;
private IMongoDatabase database;
public static readonly Dal Instance = new Dal();
private Dal()
{
client = new MongoClient("mongodb://localhost:27017/?maxPoolSize=555");
database = client.GetDatabase("ChartPicFullChs");
//var collection = database.GetCollection<Person>("bar");
}
public TEntity Load<TEntity>(Expression<Func<TEntity, bool>> func)
{
var tableName = (typeof(TEntity)).Name;
//System.Console.WriteLine(string.Format("func{1} begin connect : {0}", DateTime.Now.ToString("HHmmssfff"), func.Body.ToString()));
var result = database.GetCollection<TEntity>(tableName).Find(func).FirstOrDefault();
//System.Console.WriteLine(string.Format("end connect : {0}", DateTime.Now.ToString("HHmmssfff")));
return result;
}
public async Task<TEntity> LoadAsync<TEntity>(Expression<Func<TEntity, bool>> func)
{
var tableName = (typeof(TEntity)).Name;
LoggerManager.Instance._Logger.Info(string.Format("begin connect : {0}", DateTime.Now.ToString("HHmmssfff")));
var result = await database.GetCollection<TEntity>(tableName).Find(func).FirstOrDefaultAsync();
LoggerManager.Instance._Logger.Info(string.Format("end connect : {0}", DateTime.Now.ToString("HHmmssfff")));
return result;
}
}
调用方法:
同步:
public void BatchTest()
{
LoggerManager.Instance._Logger.Info(string.Format("begin synchronous test {0}", DateTime.Now.ToString("HHmmssfff")));
var dal = Dal.Instance;
for (int i = 0; i < 500; i++)
{
var url = string.Format("6508_{0}_13", 3557 + i);
//System.Console.WriteLine(string.Format("begin {1} : {0}", DateTime.Now.ToString("HHmmssfff"), url));
var desc = dal.Load<image_desc>(x => x.Id == url);
image_content pic;
if (desc != null)
pic = dal.Load<image_content>(x => x.Id == desc.md5);
//System.Console.WriteLine(string.Format("end {1} : {0}", DateTime.Now.ToString("HHmmssfff"), url));
}
LoggerManager.Instance._Logger.Info(string.Format("end synchronous test {0}", DateTime.Now.ToString("HHmmssfff")));
}
异步:
public void BatchTestAsync()
{
var dal = Dal.Instance;
var urls = new List<string>();
for (int i = 0; i < 1000; i++)
{
urls.Add(string.Format("6508_{0}_13", 3557 + i));
}
LoggerManager.Instance._Logger.Info(string.Format("begin Async test {0}", DateTime.Now.ToString("HHmmssfff")));
var results = new List<Task<byte[]>>();
LoggerManager.Instance._Logger.Info(string.Format("begin add task {0}", DateTime.Now.ToString("HHmmssfff")));
foreach (var url in urls)
{
var pic = Task.Run<byte[]>(() => GetImg(url));
results.Add(pic);
}
LoggerManager.Instance._Logger.Info(string.Format("end add task {0}", DateTime.Now.ToString("HHmmssfff")));
Task.WaitAll(results.ToArray());
LoggerManager.Instance._Logger.Info(string.Format("end Async test {0}", DateTime.Now.ToString("HHmmssfff")));
}