MS考试70-536 - 如何从线程中抛出和处理异常?

Mak*_*tar 2 .net multithreading exception-handling

MS考试70-536 .Net Foundation,第7章"线程"第1课"创建线程"中有一个文本:

请注意,因为WorkWithParameter方法接受一个对象,所以可以使用任何对象而不是它期望的字符串来调用Thread.Start.小心选择线程的起始方法来处理未知类型对于良好的线程代码至关重要.不是盲目地将方法参数转换为我们的字符串,而是测试对象类型的更好实践,如以下示例所示:

' VB
Dim info As String = o as String
If info Is Nothing Then
    Throw InvalidProgramException("Parameter for thread must be a string")
End If
// C#
string info = o as string;
if (info == null)
{
    throw InvalidProgramException("Parameter for thread must be a string");
} 
Run Code Online (Sandbox Code Playgroud)

所以,我试过这个,但是异常处理得不好(没有控制台异常输入,程序终止),我的代码有什么问题(如下)?

class Program
    {
        static void Main(string[] args)
        {
            Thread thread = new Thread(SomeWork);
            try
            {
                thread.Start(null);
                thread.Join();
            }
            catch (InvalidProgramException ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {

                Console.ReadKey();
            }
        }

        private static void SomeWork(Object o)
        {
            String value = (String)o;
            if (value == null)
            {
                throw new InvalidProgramException("Parameter for "+
                    "thread must be a string");
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

谢谢你的时间!

Dat*_*han 7

方法中的异常处理程序在Main与抛出异常不同的线程中运行.所以,异常thread就无法进入Main.请在此处查看您不希望跨线程抛出/捕获异常的原因.你应该做的是使用一个对象来包装你的线程逻辑但支持异常.例如:

class Program
{
    static void Main(string[] args)
    {
        ExceptionHandlingThreadWrapper wrapper = new ExceptionHandlingThreadWrapper();
        Thread thread = new Thread(wrapper.Run);
        try
        {
            thread.Start(null);
            thread.Join();
            if (wrapper.Exception != null)
                throw new Exception("Caught exception", wrapper.Exception);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        finally { Console.ReadKey(); }
    }
}

public class ExceptionHandlingThreadWrapper
{
    public ExceptionHandlingThreadWrapper()
    {
        this.Exception = null;
    }

    public Exception Exception { get; set; }

    public void Run(Object obj)
    {
        try
        {
            String value = obj as String;
            if (value == null)
                throw new Exception("Argument must be string");
        }
        catch (Exception ex)
        {
            this.Exception = ex;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)