Записать данные в кассандру, используя c# - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь зарегистрировать данные в Cassandra, используя c#. Поэтому моя цель - записать как можно больше данных за 200 мс. Я пытаюсь сэкономить время, случайный ключ и значение в 200 мс. Пожалуйста, смотрите код для ссылки. проблема, как я могу выполнить сеанс через некоторое время l oop.

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);
}

1 Ответ

0 голосов
/ 22 апреля 2020

Пожалуйста, предпочтите System.Threading.Timer с TimerCallback более Stopwatch.


РЕДАКТИРОВАТЬ: ( ответ на комментарий )

Привет, я не уверен, чего вы хотите достичь, но вот несколько общих понятий об асин c вызовах и параллельном выполнении. В. NET мире asyn c в основном используется для неблокирующих операций ввода / вывода , что означает, что ваш вызывающий поток не будет ждать ответа ввода / вывода О водитель. Другими словами, вы создаете экземпляр операции ввода-вывода и отправляете эту работу «вещи», которая находится за пределами экосистемы. NET и которая возвращает вам будущее (Task) , Драйвер подтверждает назад, что он получил запрос, и обещает , что он обработает его, как только у него появится свободная емкость.

То, что Task представляет асинхронную c работу, которая либо прошла успешно, либо завершилась неудачей. Но поскольку вы вызываете его асинхронно, вы не ожидаете его результата ( не блокирует поток вызывающей стороны для ожидания внешней работы ), а переходите к следующему оператору. В конце концов эта операция будет завершена, и в это время водитель сообщит Task, что операция запроса завершена. (Задача может рассматриваться как основной канал связи между вызывающим абонентом и вызываемым абонентом)

В вашем случае вы используете fire и забыли асин c стиль . Это означает, что вы выполняете много операций ввода-вывода в asyn c и забыли обработать их результат. Вы не знаете ни один из них потерпел неудачу или нет. Но вы позвонили в Касандру, чтобы сделать много персонала. Измерение вашего времени используется только для выполнения заданий, а это означает, что вы не знаете, сколько из этих заданий было выполнено.

Если вы решите использовать await против ваших асинхронных c вызовов, то будет означать, что ваш while l oop будет серийно выполненным . Вы запускаете задание и не можете перейти к следующей итерации, потому что ожидаете его, поэтому ваш поток вызова переместится на один уровень выше в своем стеке вызовов и проверит, сможет ли он что-то обработать. Если также есть 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 будет использоваться для ожидания ваших вызовов кассандры или тайм-аута для завершения.

var cassandraCalls = new List<Task>();
cassandraCalls.AddRange(Enumerable.Range(0, 100).Select(_ => ExecuteAsync()));
await Task.WhenAny(Task.WhenAll(cassandraCalls), Task.Delay(1000)); 

Таким образом, вы выполнили столько заданий как вы хотели, и в зависимости от вашего драйвера они могут выполняться в параллельно или одновременно . Вы ожидаете, чтобы либо завершить sh все или прошло определенное количество времени. Когда задание WhenAny завершится, вы сможете проверить результат выполнения заданий, но просто выполните итерации по cassandraCalls

foreach (var call in cassandraCalls)
{
    Console.WriteLine(call.IsCompleted);
}

Надеюсь, это объяснение вам немного помогло.

...