If I want to dump the running processes where the company name is Microsoft I have to write a somewhat grody query:
var msProcesses = from p in processes where p.Id > 4 && p.MainModule.FileName.IndexOf(' ') == -1 && p.MainModule.FileVersionInfo.CompanyName != null && p.MainModule.FileVersionInfo.CompanyName.StartsWith("Microsoft") select new { p.MainModule.ModuleName, p.MainModule.FileVersionInfo.CompanyName }; |
If you ask for certain properties on the System or Idle processes you get exceptions and certain processes don't have a company name specified. It might be nice to have a way to coalesce nulls (kind of like Lisp or ObjC does). Is there a way to catch exceptions within the query syntax so that I can ignore certain exceptions and continue processing the query or am I stuck writing a lot of defense code in my query

Dealing with nulls and exceptions in query syntax
wiz
I started working today on a way to encapsulate retry/ignore/abort/throw logic in IEnumerable<T>.
example:
foreach (byte b in GetBytesWithTimeout(port, maxBytes, RecoveryStrategies.RetryNTimesThenAbort(maxRetries)))
{
Console.Write("{0:x2} ", b);
}
where
public static RecoveryStrategy<SerialPortReaderState, FullRecoveryOption> RetryNTimesThenAbort(int n)
{
return
delegate(Exception ex, SerialPortReaderState state)
{
if (state.RetriesAttempted < n)
{
state.RetriesAttempted++;
return FullRecoveryOption.Retry;
}
else
{
return FullRecoveryOption.Abort;
}
};
}
static IEnumerable<byte> GetBytesWithTimeout(SerialPort port, int maxBytes, RecoveryStrategy<SerialPortReaderState, FullRecoveryOption> recoveryStrategy)
{
SerialPortReaderState state = new SerialPortReaderState();
int byteCount = 0;
while (byteCount < maxBytes)
{
byte b = 0;
try
{
int read = port.BaseStream.ReadByte();
b = (byte)read;
}
catch (Exception ex)
{
Console.WriteLine("Exception Encountered: {0}", ex.Message);
FullRecoveryOption recoveryOption = recoveryStrategy(ex, state);
if (recoveryOption == FullRecoveryOption.Retry)
{
Console.WriteLine("Retrying: # attempts = {0}", state.RetriesAttempted);
continue;
}
else if (recoveryOption == FullRecoveryOption.RaiseException)
{
throw ex;
}
else if (recoveryOption == FullRecoveryOption.Abort)
{
Console.WriteLine("in Abort");
yield break;
}
else if (recoveryOption == FullRecoveryOption.Ignore)
{
continue;
}
}
byteCount++;
yield return (byte)b;
}
}
Oddly, I seem to have encounted a strange bug in the debugger or compiler, where if I issue the continue in that if/else/if block in GetBytesWithTimeout, it'll actually jump to the yield break for FullRecoveryOption.Abort (skipping the Console.WriteLine on the previous line) before looping back. It behaves the same if it's a switch block.
I'm being coerced into turning this into an article somewhere, but it needs more time to simmer.
Larry Guger
I wonder if the coolest feature to come out of LINQ is the fact that it is extensible. Nice extension!
tomahawk009
Actually, I've been dealing mostly with querying cell phones for their debug logs (my company writes cell phone software -- anybody here using a Samsung A840 ).