0

在 Visual C# 中,我编写了一个自定义 UserControl,它将在计算机上搜索设备。

例子:

public class MyControl : UserControl
{
    private Thread _searchThread;
    private bool _found;

    public MyControl()
    {
        InitializeComponents();
        _searchThread = new Thread(search);
        _searchThread.Start();
    }

    private void search()
    {
        while(!_found)
        {
            //search
        }
    }
}

当我将此控件添加到另一个控件时,我得到一个设计时错误,这个堆栈跟踪的 FileNotFound 异常:

StackTrace:在 MyControl.search() 在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 在 System.Threading.ExecutionContext.Run( System.Threading.ThreadHelper.ThreadStart() 处的 ExecutionContext executionContext、ContextCallback 回调、对象状态

现在,当我注释掉 _searchThread.Start() 时,一切正常。

有谁知道这里发生了什么或如何解决这个问题?

4

2 回答 2

3

有谁知道这里发生了什么或如何解决这个问题?

如前所述,控件在设计时使用默认构造函数进行实例化。要修复它,请考虑从构造函数中获取副作用(如搜索和其他仅运行时的操作),添加一个在运行时显式调用的单独方法。

public MyControl()
{
    InitializeComponents();
}


public void Activate() 
{
    if (_activated) 
    {
        return;
    }

    _activated = true;
    _searchThread = new Thread(search);     
    _searchThread.Start();
}
于 2012-07-18T21:34:34.200 回答
1

好吧,在设计时 Visual Studio 尝试实例化MyControl,因此它正在执行控件的(默认)构造函数。但是,构造函数是在受限环境中执行的,因此可能不满足您search()期望的先决条件(其他全局对象当然不可访问)。所以你的代码崩溃了。

你能做什么?嗯,很简单:你可以检测到你是由 Visual Studio Designer 运行的,在这种情况下不要启动线程。

像这样的东西:

public MyControl()
{
    InitializeComponents();
    if (DesignerProperties.GetIsInDesignMode(this))
        return;
    _searchThread = new Thread(search);
    _searchThread.Start();
}
于 2012-07-18T21:28:47.160 回答