AppDomain.DoCallBack返回System.Runtime.Serialization.SerializationException

时间:2015-08-02 20:05:29

标签: c#

我一直在努力     An exception of type 'System.Runtime.Serialization.SerializationException' occurred in IRCBot.exe but was not handled in user code 来自AppDomain.DoCallBack

我的代码是

            object result = null;
        try {
            Console.WriteLine("Attempting to run in sandbox");
            sandbox.DoCallBack(() =>
            {
                Console.WriteLine("Creating thread");
                try
                {
                    var scriptThread = new Thread(() =>
                    {
                        try
                        {
                            Console.WriteLine("Trying");
                            result = CSharpScript.RunAsync(code).ReturnValue.Result;
                        }
                        catch (Exception ex)
                        {
                            result = ex.Message;
                        }
                    });
                    scriptThread.Start();

                    if (!scriptThread.Join(6000))
                    {
                        scriptThread.Abort();
                        AppDomain.Unload(sandbox);
                    }
                }
                catch (Exception ex)
                {
                    result = ex.ToString();
                }
            });
        }
        catch (Exception e)
        {
            result = e.ToString();
        }

很抱歉,如果这个问题听起来很简短,但我真的不知道还有什么可说的。我已经找到了DoCallBack异常的来源。提前谢谢。

1 个答案:

答案 0 :(得分:3)

传递给DoCallback的委托必须代表静态方法或可序列化类的方法。由C#编译器为lambda表达式自动生成的类是不可序列化的。您需要实现应该在可序列化类上调用的方法,例如

[Serializable]
class CallbackContext
{
    public string Code { get; set; }
    public void Entry()
    {
        Console.WriteLine("Creating thread");
        try
        {
            var scriptThread = new Thread(() =>
            {
                try
                {
                    Console.WriteLine("Trying");
                    AppDomain.CurrentDomain.SetData("result", CSharpScript.RunAsync(Code).ReturnValue.Result);
                }
                catch (Exception ex)
                {
                    AppDomain.CurrentDomain.SetData("result", ex.Message);
                }
            });
            scriptThread.Start();

            if (!scriptThread.Join(6000))
            {
                scriptThread.Abort();
                AppDomain.Unload(AppDomain.CurrentDomain);
            }
        }
        catch (Exception ex)
        {
            AppDomain.CurrentDomain.SetData("result", ex.ToString());
        }
    }
}

    ...

    object result = null;
    try {
        Console.WriteLine("Attempting to run in sandbox");
        CallbackContext ctx = new CallbackContext();
        ctx.Code = code;
        sandbox.DoCallBack(ctx.Entry);
        result = sandbox.GetData("result");
    }
    catch (Exception e)
    {
        result = e.ToString();
    }