For logging in particular, a common pattern is to always have synchronous log methods that actually just write to an in-memory queue, which is asynchronously written to the actual data store by a separate actor. So the log methods themselves are naturally synchronous (updating an in-memory queue), while the actual log writes (e.g., InsertLogItem
) remain asynchronous but not directly called by the logging methods. Since it looks like you're writing your own logging framework (for some reason), I'd recommend this approach.
If you choose not to take the queue approach, then the next-recommended approach is to either go asynchronous all the way or synchronous all the way.
Ideally, your code should be synchronous or asynchronous all the way up. You currently have a method that is asynchronous (e.g., LogCrash
). So ideally you should either make all the calling code asynchronous or make LogCrash
synchronous.
// Ideal option #1
public async Task<bool> ArrangeCardOrder(bool IsFirstToLast)
{
try
{
// Do stuff
}
catch (Exception ex)
{
await Helper.LogCrash();
return false;
}
}
public static async Task LogCrash(string ex)
{
... // unchanged
}
or the synchronous option:
// Ideal option #2
public bool ArrangeCardOrder(bool IsFirstToLast)
{
try
{
// Do stuff
}
catch (Exception ex)
{
Helper.LogCrash();
return false;
}
}
public static void LogCrash(string ex)
{
try
{
var logCrash = new Cosmos.LogCrash()
{
Ex = exception
};
App.CDB.InsertLogItem(logCrash);
}
catch (Exception)
{
}
}
Note that the synchronous option assumes that InsertLogItem
is made synchronous as well.
The next-recommended option is to actually fire-and-forget. Unlike the queue-based approach, fire-and-forget will prevent you from being aware of any logging exceptions. To do fire-and-forget, you can just call the asynchronous method and ignore the task it returns:
public static void LogCrash(string ex)
{
try
{
var logCrash = new Cosmos.LogCrash()
{
Ex = exception
};
var _ = App.CDB.InsertLogItem(logCrash);
}
catch (Exception)
{
}
}
If none of these options are desirable, then you can use a hack to call asynchronous code from synchronous code.