I am upgrading the Couchbase client SDK version from .NET client SDK 2.7.14 to .NET client SDK 3.2.2 in my application which is developed in Dot net framework 4.8. While inserting the key value data on Couchbase server I am getting an error as “Thread was being aborted”. Can you please suggest.
Below is the stack trace.
at Couchbase.KeyValue.CouchbaseCollection.d__301.MoveNext() at System.Runtime.CompilerServices.AsyncTaskMethodBuilder1.Start[TStateMachine](TStateMachine& stateMachine)
at Couchbase.KeyValue.CouchbaseCollection.InsertAsync[T](String id, T content, InsertOptions options)
at Serilog.Sinks.Couchbase.CouchbaseSink.d__12.MoveNext()
Source : Couchbase.NetClient
Below is the code
private async void InsertAsync(ValueTask _bucketAsync, string key, LogEvent logEvent, IServerConnectionInfo info)
{
try
{
var collection = (await _bucketAsync).DefaultCollection();
IOperationResult<Data.LogEvent> result = (IOperationResult<Data.LogEvent>)collection.InsertAsync(key, new Data.LogEvent(logEvent)).GetAwaiter().GetResult();
if (!result.Success)
{
SelfLog.WriteLine($"Failed to store value into bucket {info.BucketName}");
}
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
Your problem is most likely that you are not correctly following the async pattern. Generally speaking you should not use GetAwaiter().GetResult() within an asynchronous method. Instead, you should be using the await keyword. There are some exceptions if you really know what you’re doing, but for most uses GetAwaiter().GetResult() is an anti-pattern.
IOperationResult<Data.LogEvent> result = (IOperationResult<Data.LogEvent>)(await collection.InsertAsync(key, new Data.LogEvent(logEvent)));
Yes True. Actually I tried async pattern but same issue was occurred. I think the problem is all calling methods are not async. I am using the Serilog.Sinks.PeriodicBatching EmitBatch() method and using that override method I am calling this InsertAsync() method. I did EmitBatch() method also as async and it worked once but second time it giving me the same error message.
Unfortunately, you are running into the sorts of problems that have been giving .NET developers headaches for years. Calling asynchronous code from synchronous code is fraught with peril. And Couchbase SDK 3.x is written to take the modern approach of all async.
Your best bet, if possible, would be to refactor your code to be async all the way back. But I seriously doubt that’s possible with Serilog, logging generally being a synchronous process. Your change to using async void on EmitBatch is basically turning that function into a “fire-and-forget” function where the caller (Serilog) isn’t waiting for completion before moving on.
It’s also possible that your error isn’t directly related. ThreadAbortException is normally fired when a given thread is being shut down. This async work should be running on the thread pool, is it possible that you’re only encountering the error when your application exits because it’s shutting down the thread pool before the logging work is done? Perhaps the stack trace from the exception would help us learn more.
Enabling logging and analyzing the logs may be helpful as well. As @btburnett3 said, ThreadAbortException are thrown when a thread is shutdown and were using the threadpool throughout. Perhaps its not directly related and the error is occurring when the app shuts down?
Also, your awaiting on void and not Task, that may be related somehow. Not sure you have a choice given the API provided by Serilog.