为何C#程序中Exception.Message无法以英文显示?
Let's break down why you're seeing garbled exception messages, even after switching the thread's culture to en-US in your catch block:
Root Cause
The key issue here is timing: Exception messages are localized at the moment the exception is thrown, not when you access Exception.Message later.
When the SocketException was thrown by the underlying .NET code, your thread was still using its original culture (likely a non-English one with a different character encoding). The exception message was generated using that culture's encoding. Later, when you switch to en-US in the catch block, you're too late— the message's content and encoding were already fixed when the exception was raised. The garbled text happens because your logger is trying to interpret the originally encoded message using a mismatched encoding (probably the en-US default, which doesn't align with the original culture's encoding).
Solutions to Fix This
Here are three actionable ways to get proper English exception messages:
Set Global Culture at Startup
If your application can use en-US culture globally, set the default thread cultures at the very start of your program (e.g., in theMainmethod). This ensures all exceptions are generated with English messages from the get-go:using System.Globalization; using System.Threading; static void Main(string[] args) { CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US"); // Rest of your application code }Temporarily Switch Culture Before Risky Code
If you can't set the global culture, switch to en-US right before executing the code that might throw exceptions, then revert back in afinallyblock:using System.Globalization; using System.Threading; using System.Net; public bool DownloadFile(string url, string name) { // Save original culture settings var originalCulture = Thread.CurrentThread.CurrentCulture; var originalUICulture = Thread.CurrentThread.CurrentUICulture; try { // Switch to en-US before executing code that may throw Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US"); using (var client = new WebClient()) { client.DownloadFile(url, name); return true; } } catch (Exception e) { Logger.Error("Error inside DownloadFile"); Logger.Error(e.Message); Logger.Error(e.InnerException?.ToString()); return false; } finally { // Restore original culture to avoid side effects Thread.CurrentThread.CurrentCulture = originalCulture; Thread.CurrentThread.CurrentUICulture = originalUICulture; } }Fetch English Messages Directly from .NET Resources (Advanced)
If you need to retrieve English messages for already-thrown exceptions, you can use .NET'sResourceManagerto pull the English version of the message using the exception's error code. This works well for specific exception types likeSocketException:using System.Resources; using System.Globalization; using System.Net.Sockets; catch (SocketException se) { var resourceManager = new ResourceManager( typeof(SocketException).FullName, typeof(SocketException).Assembly ); string englishMessage = resourceManager.GetString( se.ErrorCode.ToString(), new CultureInfo("en-US") ); Logger.Error(englishMessage); }
Quick Recap
The core mistake was setting the culture after the exception was thrown. Exception messages are baked with the culture that was active when the exception occurred. By setting the culture earlier (either globally or right before risky operations), you'll get properly formatted English messages without garbling.
内容的提问来源于stack exchange,提问作者Ijas

