我试图使用c#将数据记录到Cassandra中。所以我的目的是在200ms内记录尽可能多的数据点。我试图节省时间,在200ms内随机键和值。问题是我怎么能在while循环后执行session。
Cluster cluster = Cluster.Builder()
.AddContactPoint("127.0.0.1")
.Build();
ISession session = cluster.Connect("log"); //keyspace to connect with
var ps = session.Prepare("Insert into logcassandra(nanodate, key, value) values (?,?,?)");
stopwatch.Start();
while(stop.ElapsedMilliseconds <= 200)
{
i++;
var statement = ps.Bind(nanoTime(),"key"+i,"value"+i);
session.ExecuteAsync(statement);
}
请选择 System.Threading.Timer 附带 TimerCallback
在...上 Stopwatch
.
编辑:(回复评论)
你好,我不知道你想实现什么,但这里有一些关于async调用和并行执行的一般概念。在.NET世界中,async主要用于 非阻塞式IO操作,这意味着你的调用者线程 不等不靠 的IO驱动。换句话说,你实例化了一个IO操作,并将这个工作派遣到一个.NET生态系统之外的 "事物 "上,而这个 "事物 "会给你返回一个 未来 (a Task
). 驱动程序 承认 回报说它收到了请求,它 承诺 一旦它有了空闲的容量就会处理它。
那 Task
代表一个异步工作,要么成功,要么失败。但因为你是异步调用它,所以你没有等待它的结果 (不阻止调用者线程等待外部工作。),而是进入下一个语句。最终这个操作会完成,这时驱动程序会通知说 Task
表示请求操作已经完成。(任务可以看作是呼叫者和被呼叫者之间的主要通信渠道)
在您的情况下,您使用的是 火烧眉毛 风格的异步调用。这意味着你在async中发射了很多IO操作,而你却忘了处理它们的结果。你既不知道它们中的任何一个失败了,也不知道它们没有失败。但是你调用了卡桑德拉做了很多工作人员。你的时间测量只用于发射作业,这意味着你不知道这些作业有多少已经完成。
如果你选择使用 await
的异步调用,这就意味着你的while循环将是 连续执行. 你会发射一个作业,但你不能继续下一个迭代,因为你在等待它,所以你的调用线程会在它的调用堆栈中往上移动一级,并检查它是否可以处理一些东西。如果有一个 await
也是,那么它就会更高一层,以此类推......
while(stop.ElapsedMilliseconds <= 200)
{
await session.ExecuteAsync(statement);
}
如果你不希望串行执行,而是 平行,你可以根据自己的需要,创造出多少个工作岗位,并作为一个整体来等待他们。这就是 Task.WhenAll
进入游戏。你会发射出很多作业,你会等待那个能跟踪其他所有作业的单一作业。
var cassandraCalls = new List<Task>();
cassandraCalls.AddRange(Enumerable.Range(0, 100).Select(_ => session.ExecuteAsync(statement)));
await Task.WhenAll(cassandraCalls);
但是这段代码会一直运行到所有的作业完成。如果你想约束整个执行时间,那么你应该使用一些 取消 机制。Task.WhenAll
不支持 CancellationToken
. 但你可以通过几种方式来克服这个限制。最简单的解决方案是结合 Task.Delay
和 Task.WhenAny
. Task.Delay
将用于超时,而 Task.WhenAny
将用于等待您的cassandra调用或超时完成。
var cassandraCalls = new List<Task>();
cassandraCalls.AddRange(Enumerable.Range(0, 100).Select(_ => ExecuteAsync()));
await Task.WhenAny(Task.WhenAll(cassandraCalls), Task.Delay(1000));
这样一来,你已经启动了许多你想要的工作,根据你的驱动,它们可能会在 平行 或 同时. 您正在等待全部完成或经过一定的时间。当 WhenAny
作业完成后,你就可以检查作业的结果,但只是简单地迭代一遍 cassandraCalls
foreach (var call in cassandraCalls)
{
Console.WriteLine(call.IsCompleted);
}
希望这个解释对你有点帮助。