C#从线程中的外部DLL获取事件时出现问题

C#从线程中的外部DLL获取事件时出现问题,c#,multithreading,C#,Multithreading,我有一个C#WPF桌面应用程序,它使用外部DLL控制设备 连接到外部DLL是通过以下事件完成的(服务对象是外部DLL的一部分): 只要我从主线程调用,它就会工作。显然,我不希望DLL阻止主线程和UI线程。所以我想把设备DLL的工作放在它自己的线程中 private Device device; ... deviceThread = new Thread(new ThreadStart(InitializeThread)); deviceThread.IsBackground = true;

我有一个C#WPF桌面应用程序,它使用外部DLL控制设备

连接到外部DLL是通过以下事件完成的(服务对象是外部DLL的一部分):

只要我从主线程调用,它就会工作。显然,我不希望DLL阻止主线程和UI线程。所以我想把设备DLL的工作放在它自己的线程中

private Device device;

...

deviceThread = new Thread(new ThreadStart(InitializeThread));
deviceThread.IsBackground = true;
deviceThread.Start();
...
private void InitializeThread()
{
  device = Device.MyDevice;
  device.Init();
  logger.Debug("Waiting for work . . .");
  while (running)
  {
      if (work != null)
      {
          work();

          work = null;
      }
  }
}
但是,当我尝试像之前那样连接到DLL时,ServiceConnected事件从未在线程中捕获。唯一的区别是Init()调用是从新线程完成的

该设备在我的代码中是一个单例:

private Device()
{
}

public static Device MyDevice
{
    get
    {
        return Nested.instance;
    }
}

private class Nested
{
    static Nested()
    {
    }

    internal static readonly Device instance = new Device();
}
为什么DLL不能在自己的线程中工作? 我的代码中有原因吗? 外部DLL的哪些属性可能导致此类行为


Thx预先

我用一个简单的服务存根做了这个简单的测试,事件被捕获了。也许你想做些不同的事

public partial class Form1 : Form
{
    private Device device;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Thread deviceThread = new Thread(new ThreadStart(InitializeThread));
        deviceThread.IsBackground = true;
        deviceThread.Start();
    }

    private void InitializeThread()
    {
        device = Device.MyDevice;
        device.Init();
        /*
        while (running)
        {
           if (work != null)
           {
              work();

              work = null;
           }
        }
        */
    }
}

class Service
{
    public event EventHandler Connected;

    public Service(string name)
    {

    }

    public void Connect()
    {
        System.Threading.Thread.Sleep(2000);

        Connected(this, new EventArgs());
    }
}

class Device
{
    private Device()
    {
    }

    public static Device MyDevice
    {
        get
        {
            return Nested.instance;
        }
    }

    private class Nested
    {
        static Nested()
        {
        }

        internal static readonly Device instance = new Device();
    }

    public void Init()
    {
        Service service = new Service("service");
        service.Connected += new EventHandler(ServiceConnected);
        service.Connect();
    }

    private void ServiceConnected(object sender, EventArgs e)
    {
        //do more stuff

        Console.WriteLine("ServiceConnected");
    }
}

Init()方法必须有一个阻塞方法,因此它不会从Init返回。您能在设备端确认您的应用程序至少连接到它吗?是的,可能Init()正在阻塞,因为当我从主线程调用时,主线程被阻塞,直到调用ServiceConnected为止。但为什么它只在主线程上工作,而不在其他线程上工作。我可以确认DLL和设备工作正常。“外部DLL”太模糊了。但可以肯定的是,这种情况并不少见,有些人的库在设计上几乎从来都不是线程安全的,可能需要一个带有调度程序的STA线程才能正常工作。在做任何激烈的事情之前,先和图书馆老板商量一下。谢谢。。。我假设在您的例子中,无论是否使用线程调用服务,其行为都是相同的。在我的例子中,服务是外部DLL的一部分,我无法控制它(除了一些参数)。我尝试将服务放入外部程序集中,并从主项目引用它,但成功了。我认为您需要在代码中进行更深入的研究,因为代码结构是正确的。谢谢-这意味着很可能是外部DLL导致了这种行为?我尝试在单独的DLL中使用服务,它可以工作。尝试使用调试器,如果没有帮助,可以尝试分而治之的方法,例如使用我以前使用的类存根简化外部DLL行为。希望有帮助!外部DLL来自第三方,因此我将与他们联系,看看他们是否能提供帮助…谢谢
public partial class Form1 : Form
{
    private Device device;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Thread deviceThread = new Thread(new ThreadStart(InitializeThread));
        deviceThread.IsBackground = true;
        deviceThread.Start();
    }

    private void InitializeThread()
    {
        device = Device.MyDevice;
        device.Init();
        /*
        while (running)
        {
           if (work != null)
           {
              work();

              work = null;
           }
        }
        */
    }
}

class Service
{
    public event EventHandler Connected;

    public Service(string name)
    {

    }

    public void Connect()
    {
        System.Threading.Thread.Sleep(2000);

        Connected(this, new EventArgs());
    }
}

class Device
{
    private Device()
    {
    }

    public static Device MyDevice
    {
        get
        {
            return Nested.instance;
        }
    }

    private class Nested
    {
        static Nested()
        {
        }

        internal static readonly Device instance = new Device();
    }

    public void Init()
    {
        Service service = new Service("service");
        service.Connected += new EventHandler(ServiceConnected);
        service.Connect();
    }

    private void ServiceConnected(object sender, EventArgs e)
    {
        //do more stuff

        Console.WriteLine("ServiceConnected");
    }
}