调用CreateInstance会导致线程错误

时间:2013-05-01 13:35:44

标签: c# .net reflection

我创建了小型便携式库(reference,目标是:Windows,Windows 8,Windows Phone 7.5)用于教育目的。我决定在我的小型Windows 8 Metro风格应用程序中使用它。不幸的是,当我从库中调用方法时会抛出异常:

  

该应用程序调用了一个为不同线程编组的接口。

在以下行:

return Activator.CreateInstance(outputType, constructorArguments.ToArray());

Resolve method outputType typeof(ClassFromMyMetroStyleApp)。 库将作为dll引用添加到项目中。

我该怎么做才能解决这个问题?

编辑:  方法是在Metro Style App解决方案中从UnitTest调用:

[TestClass]
public class ResolvingTypesTests
{
    /// <summary>
    /// The school context interface test.
    /// </summary>
    [TestMethod]
    public void SchoolContextTest()
    {
        var schoolContext = TypeService.Services.Resolve<ISchoolContext>();

        Assert.AreEqual(typeof(SchoolCollection), schoolContext.GetType());
    }
}

其中 TypeService 是静态类,服务是IResolvable类型的静态属性(接口由库提供)。

服务属性:

/// <summary>
    /// The resolvable.
    /// </summary>
    private static IResolvable resolvable;

    /// <summary>
    /// Gets the type services.
    /// </summary>
    public static IResolvable Services
    {
        get
        {
            if (resolvable == null)
            {
                var builder = new ContainerBuilder();
                builder.Register();
                resolvable = builder.Build();
            }

            return resolvable;
        }
    }

3 个答案:

答案 0 :(得分:0)

当您在另一个线程中创建的一个线程中使用某些对象(通常是UI对象)时,您可以在单线程单元中出现此错误。

答案 1 :(得分:0)

找到解决方案(感谢Hans Passant的线索!) 需要向测试方法添加属性:

[UITestMethod]

答案 2 :(得分:-1)

不仅因为跨线程访问而且还因为性能原因,不建议使用Activator。 http://bloggingabout.net/blogs/vagif/archive/2010/04/02/don-t-use-activator-createinstance-or-constructorinfo-invoke-use-compiled-lambda-expressions.aspx

这里作者提供了Activator与使用Lambda表达式来实例化对象之间的比较。 我把代码包装在一个单独的方法中。试试这个

public object CreateObject(Type type)
    {

        var ctor = type.GetConstructor(new Type[]{});
        // Make a NewExpression that calls the ctor with the args we just created
        NewExpression newExp = Expression.New(ctor, null);

        // Create a lambda with the New expression as body and our param object[] as arg
        LambdaExpression lambda = Expression.Lambda(newExp, null);

        // Compile it
        var compiled = lambda.Compile();
        if (compiled != null)
        {
        }
        return compiled.DynamicInvoke();
    }