0
votes

In Visual C#, I wrote a custom UserControl that will search for a device on the computer.

Example:

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
        }
    }
}

When I add this control to another control I get a design time error, FileNotFound exception with this stack trace:

StackTrace: at MyControl.search() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()

Now when I comment out the _searchThread.Start() everything works.

Does anyone know what is happening here or how to fix this?

2
Chances are ou shouldn't be starting that thread during the construtor. You should probably wait for the Load event. - John Saunders
Starting the thread in the Load event still throws this error. - dkellycollins

2 Answers

3
votes

Does anyone know what is happening here or how to fix this?

As was mentioned before the control is instantiated with default constructor at design time. To fix it consider taking side-effects (like searching and other runtime-only actions) from the constructor adding a separate method called expicitly at runntime.

public MyControl()
{
    InitializeComponents();
}


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

    _activated = true;
    _searchThread = new Thread(search);     
    _searchThread.Start();
}
1
votes

Well, at the design time Visual Studio tries to instantiate MyControl, so it's executing the control's (default) constructor. However, the constructor is executed in a constrained environment, so perhaps the preconditions which your search() expects are not met (other global objects are of course not accessible). So your code crashes.

What can you do? Well, it's simple: you can detect that you are run by the Visual Studio Designer, and do not start the thread in this case.

Something like this:

public MyControl()
{
    InitializeComponents();
    if (DesignerProperties.GetIsInDesignMode(this))
        return;
    _searchThread = new Thread(search);
    _searchThread.Start();
}