I have written a windows service in .NET 4 that uses the FirebirdSql.Data.FirebirdClient ADO.NET provider v4.5.2.0.
The service depends on capturing events posted by the firebird Db to perform it's tasks.
The code I use to subscribe to the relevant events is:
<!-- language: lang-cs -->
public void SetFirebirdEventListeners()
{
string[] fbEvents = new string[] { "QueueUpdate", "DispensedSupplyUpdate", "QueueInsert", "DispensedSupplyInsert" };
try
{
fbRemoteEvent = new FbRemoteEvent(fbConn);
fbRemoteEvent.AddEvents(fbEvents);
// Add callback to the Firebird events
fbRemoteEvent.RemoteEventCounts += new FbRemoteEventEventHandler(FbEventHandler);
// Queue events
fbRemoteEvent.QueueEvents();
WriteEventToLog();
}
catch (Exception ex)
{
log.Error("Error setting firebird event listeners. {0}Message:{1}Stacktrace:{2}", Environment.NewLine + Environment.NewLine, ex.Message + Environment.NewLine, ex.StackTrace);
throw;
}
}
The connection to firebird stays open as long as the service is running.
This works fine for a period of time (usually hours), however seemingly at random the service simply stops receiving events. No exceptions are thrown.
Has anyone ever encountered this issue with Firebird and found the cause? I can't see anuthing in the documentation. Is there a way of receiving a warning that the service is no longer subscribed to events?
You are likely confronted with a race condition in the way Firebird registers and notifies events. This bug will be fixed in Firebird 2.5.8 and Firebird 3.0.3. See CORE-5521 for details.
Related
I have a Win11, NET 6.0, Windows App that calls Word through COM to run a Word macro stored inside of the Word instance. All the relevant code has been running for a year or so. I have been debugging for two days without success, reading up on the exception message that I am suddenly getting, trying random code changes, and so on.
My C# program gets the Word instance and tries to run the macro named "FH3" as shown in the code and log trace below. But the code never gets to run the macro because the code that tries to get the Word instance (WordAppGet) fails at runtime. Here are three lines from my log file that show the execution and exception error message.
MacroRun Running Word macro: 'FH3'
WordAppVarsGet GetActiveObject Word.Application failed.
Exception: An outgoing call cannot be made since the application is dispatching an input-synchronous call. (0x8001010D (RPC_E_CANTCALLOUT_ININPUTSYNCCALL))
The following test case code runs okay in Visual Studio.
[TestMethod()]
public void MacroRunTest() {
var me = MethodBase.GetCurrentMethod()?.Name;
MacroRunHelper("FH2", me);
}
// this code has been running fine for many months
public static void
MacroRunHelper(string macroName, string me) {
var msg1 = $"{me} Running Word macro: '{macroName}'";
LogMan.SendNormal(msg1);
var wapp = WordAppGet();
try {
wapp.Run(macroName);
}
catch (Exception ex) {
var msg = $"{me} {ex.Message} '{macroName}'";
LogMan.Send(LogType.Error, msg);
}
}
/// <summary>
/// Get and store a reference to the active Word application.
/// </summary>
public static Word.Application
WordAppGet() {
Word.Application wapp = null;
try {
// Marshal2.GetActiveObject is a copy of the Microsoft reference code
// because it was not included in the MS Interop library when the code was written.
// And GetActiveObject is still not included as of 2022-09-18.
//
// this call fails with the error message
wapp = Marshal2.GetActiveObject("Word.Application") as Application;
}
catch (Exception ex) {
var msg = $"{me} GetActiveObject Word.Application failed.";
LogMessage(PError, msg);
LogMessage(PError, ex.Message);
throw;
}
return wapp;
}
For what it's worth, the online doc about the error message talks a lot about windows controls and BeginInvoke, but this has nothing to do with any Windows controls as far as I can tell.
I have used this same code pattern to access Word, Excel, Outlook, PowerPoint, on NET Framework for a couple of years, and on NET 5 and 6 for more than a year.
It is a mystery to me why it stopped working for Word. It is a mystery to me why it continues to work in the Visual Studio debugger.
Does anyone know how I can fix it to run again? I wonder if any recent Win11 updates have had any changes that break this kind of code. Thank you.
The source of the problem was far away from the code shown above. I switched my top-level WindowsApp from receiving input commands using sockets to receiving using Windows messages. The WndProc branch called some helper code SYNCHRONOUSLY which called other code, and about 10 or 15 calls down the WordAppGet code was called.
Because WndProc calls were synchronous, the WndProc thread was not allowed to "call out" over COM because it might create a deadlock condition. Using Task.Run(...) in the WndProc message branch put the work on a separate thread that was allowed to call out over COM.
Receiving input commands via sockets does not involve the single-thread STA WndProc thread, so sockets worked for a year or more. I was trying to improve the speed of the code and thought Windows messages would be faster. But I wasted more time debugging the COM issue than sockets execution times would have used in 20 years. Bummer.
FWIW, I did not detect the problem until many weeks after I switched from sockets to messages because the COM use case was not tested after the switch.
Application exists unexpectedly during iterating over IAsyncEnumerable and inserting records to database using EF context. No error or exception is thrown. In the console window it shows only The program '[5372] XYZ.exe' has exited with code 3 (0x3).
The code is somthing like:
public async Task LoadDataAsync()
{
try
{
_context.ChangeTracker.AutoDetectChangesEnabled = false;
int bufferSize = 50;
var myEntityBuffer = new List<MyEntity>(bufferSize);
//GetDataAsync returns IAsyncEnumerable
await foreach (var element in loader.GetDataAsync(cancellationToken).WithCancellation(cancellationToken))
{
myEntityBuffer.Add(new MyEntity(element));
if (addressPointBuffer.Count == bufferSize)
{
_context.MyEntities.AddRange(myEntityBuffer);
await _context.SaveChangesAsync(cancellationToken);
myEntityBuffer = new List<MyEntity>(bufferSize);
_context.ChangeTracker.Clear();
}
}
await _context.SaveChangesAsync(cancellationToken);
}
catch (Exception ex)
{
_logger.LogError(ex, ex.Message);
}
finally
{
_context.ChangeTracker.AutoDetectChangesEnabled = true;
}
}
The same pattern is used by other commands and they work fine, I could not spot the difference except that the element structure is different, different entity. The number of records is large, but the application exists after inserting approx. 80 000 record (the number differs from run to run)
I cannot trace the source of the problem and what makes the application exit. I run this on Development environment.
I appreciate if you could suggest how to trace the issue
So far I have tried the following:
Checking the application Logs - the running code is wrapped with try-catch, however no error were thrown and logged
placing a breakpoint in catch and finally blocks (these lines are not reached)
Wrapping Main method code in try-catch (no execption was catched)
Adding IHostApplicationLifetime Stopped and OnStopping events (these events are not raised upon exit)
increasing logging level for Microsoft.EntityFramework to Debug (I can see only SQL commands but no issues)
If I comment out lines doing database operations (AddRange, SaveChangesAsync) the method completes without issues and the application is still running.
I use the following stack
.NET Runtime 5.0.11
ASP.NET Core Runtime 5.0.11
.NET Desktop Runtime 5.0.11
EntityFramework Core + NetTopologySuite
SQLite + Spatialite
UPDATE
I have stopped using SQLite. I had plans to move to postgresql anyway. On postgresql it does not happen. Still would be nice to know how to diagnose such issues...
We have been using RabbitMQ as messaging service in the project. We will be pushing message into a queue and which will be received at the message consumer and will be trying to make entry into database. Once the values entered into the database we will be sending positive acknowledgement back to the RabbitMQ server if not we will be sending negative acknowledgement.
I have created Message Consumer as Windows service.Message has been successfully entered and well received by the message consumer(Made entry in table)but with an exception log "Shared Queue closed".
Please find the code block.
while (true)
{
try
{
if (!Connection.IsOpen || !Channel.IsOpen)
{
CreateConnection(existConnectionConfig, QueueName);
consumer = new QueueingBasicConsumer(Channel);
consumerTag=Channel.BasicConsume(QueueName,false,consumer);
}
BasicDeliverEventArgs e = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
IBasicProperties props = e.BasicProperties;
byte[] body = e.Body;
bool ack = onMessageReceived(body);
if (ack == true)
{
Channel.BasicAck(e.DeliveryTag, false);
}
else
Channel.BasicNack(e.DeliveryTag, false, true);
}
catch (Exception ex)
{
//Logged the exception in text file where i could see the
//message as "Shared queue closed"
}
}
I have surfed in net too but couldn't able to what the problem. It will be helpful if anyone able to help me out.
Thanks in advance,
Selva
In answer to your question, I have experienced the same problems when my Web Client has reset the connection due to App Pool recycling or some other underlying reason the connection has been dropped that appears beyond your scope. You may need to build in a retry mechanism to cope with this.
You might want to look at MassTransit. I have used this with RabbitMQ and it makes things a lot easier by effectively providing a management layer to RabbitMQ. MassTransit takes away the headache of retry mechanisms - see Connection management. It also provides a nice multi threaded concurrent consumer configuration.
This has the bonus of your implementation being more portable - you could easily change things to MSMQ should the requirement come along.
I have a windows desktop application written with C# (Windows forms). In the code, there is a part where I use a simple try-catch exception handler. It works as expected in desktops setting, however, when deployed in Citrix it does not work at all. There is an error that I expect to fire there, I catch it and the application keeps running just fine. Anyone seen anything like it?
EDIT:
This is the code that fails. It may not say much since it is just a try catch where I execute code that is related to a specific library.
try
{
if (this.model != null)
{
if (this.model.Context.GetService<Spotfire.Dxp.Application.Document>().ActivePageReference.ActiveVisualReference != (Spotfire.Dxp.Application.Visual)this.model.Visual)
{
this.model.Context.GetService<Spotfire.Dxp.Application.Document>().ActivePageReference.ActiveVisualReference = (Spotfire.Dxp.Application.Visual)this.model.Visual; //In certain conditions this line may fail, so I trap it.
}
}
}
catch (Exception exc)
{
//System.Diagnostics.Debug.WriteLine(exc.Source + " " + exc.Message + "\n" + exc.StackTrace);
}
I added a comment to the line that fails. I trap the error and it works just fine. The thing is that when it is deployed to citrix it fails to trap the error and it actually crashes the application. Thus my inclination to think that it is something related to citrix.
Thanks!
I am having stability issues using a named pipe for communication between a C# and Java app.
Here is the code that sets up the named pipe in C# and reads lines of XML strings.
try
{
NamedPipeServerStream inStream = new NamedPipeServerStream(inName, PipeDirection.In);
inStream.WaitForConnection();
reader = new StreamReader(inStream);
while (!Stopped && !reader.EndOfStream)
{
string xml = reader.ReadLine();
processXml(xml);
}
}
catch (Exception e)
{
log.Error("Error in receiver", e);
}
finally
{
log.Info("Receiver ended");
}
And here is the connection and write code in Java
public void connect() throws TransportUnavailableException
{
try
{
File inPipe = new File(inName);
os = new FileOutputStream(inPipe);
// Uses JAXB for XML serialization
marshaller = context.createMarshaller();
}
catch (FileNotFoundException e)
{
throw new TransportUnavailableException("Named pipe not found: " + inName);
}
}
public void send(Message message)
{
marshaller.marshal(message, os);
os.write('\n');
os.flush();
}
Everything works fine normally. But many users are reporting crashes. I don't see any exceptions in logs that suggest a reason for the pipe dying. I just see that the receiving thread in C# ends (i.e. 'Receiver ended' in the logs) and after this I get an IO exception on the next attempted send from Java with a message 'The handle is invalid'. This seems to happen randomly, but usually within the 1st minute or 2 after the connection was established. The pipe ending message also happens when the application is not doing anything, it could have been minutes since the last user operation. Then it could be a few more minutes before the next write is attempted from Java.
All reasons for my app to bring down the pipe on purpose (e.g. a crash elsewhere in system) are logged and I never see that as a reason for the pipe ended, I just get the message that the reader has given up reading.
Could there be any external reason for the pipe being killed, anti-virus, firewall etc?
I noticed I didn't use a RandomAccessFile from Java like most examples seem to use. Could this be a reason?
Any help/suggestion appreciated
Thanks!
Your server side code only processes one connection, then it exits when it reads to EOS. You need to create the named pipe, loop accepting connections, and spin up a new thread to handle each connection. You also need to close each connection when you're finished with it.
However I would use TCP rather than named pipes for this, for several reasons.