从线程C#

时间:2018-08-27 15:53:22

标签: c++ multithreading dll com

背景:

我们已经使用 VC ++ 6.0 创建了DLL。接口中的此DLL具有将消息发送到我们的服务器的功能。因此,外部应用程序通过传递输入参数来调用DLL的函数,并且DLL使用TCP / IP将此消息发送到服务器,并返回输出给调用者。

DLL is compiled with following settings

Main of DLL looks like this

我已经在C#(框架2.0)中创建了一个samll应用程序,该应用程序创建了调用DLL函数的线程。发生的情况是第二个线程被阻塞,直到第一个线程尚未完成工作为止。

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using PAGAMENTOLib;
using log4net;
using log4net.Config;
using System.Configuration;


namespace ThreadTestAPI
{
class Program
{
    public static ILog log = LogManager.GetLogger(typeof(Program));

    argpayClass apiFunctions = new argpayClass();

    static void Main(string[] args)
    {


        XmlConfigurator.Configure();

        List<string> Ip_List = new List<string>();

        List<string> Ip_port = new List<string>();

        int MAX_THREAD = Convert.ToInt32(ConfigurationManager.AppSettings["MAX_THREAD"].ToString());

        string ReplacePattern = string.Empty;

        string IP = ConfigurationManager.AppSettings["IP"].ToString();

        string PORT = ConfigurationManager.AppSettings["PORT"].ToString();

        Program call = new Program();

        //int LastPart = Convert.ToInt32(IP.Split('*')[1]);

        //string PatterntoReplase = "*" + LastPart;

        log.Info("-------------------------------------------------------------------------");
        log.Info("                      Started Program                                     ");
        log.Info("-------------------------------------------------------------------------");

        List<Thread> ThreadList = new List<Thread>(); //Added by Asif Iqbal

        WaitAllThreads waitThreads = new WaitAllThreads();

        List<Thread> myPOSthread = new List<Thread>();

        ParamIn param = new ParamIn();

        for (int i = 0; i < MAX_THREAD; i++)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(call.CallApiFunction));

            thread.Name = "Thread " + i;


            param.Ped_ip = IP;

            log.Info("Thread Name is : " + thread.Name);

            log.Info("IP is " + param.Ped_ip);

            param.PedPort = PORT.Replace("*",i.ToString());

            log.Info("Port is " + param.PedPort);

            param.Amount = i;

            param.port_listener = "0";

            param.DatiAgg = "Thread " + i; 

            ThreadList.Add(thread);

            thread.IsBackground = true;

            thread.TrySetApartmentState(ApartmentState.MTA);


            thread.Start(param);

            myPOSthread.Add(thread);

            Console.WriteLine("***********************************************************");

            Console.WriteLine("Thread Name: " + thread.Name);

            System.Threading.Thread.Sleep(250);


        }


    }

    [MTAThread]
    public void CallApiFunction(object param)
    {



        log.Info("Calling Api function");

        ParamIn members = (ParamIn)param;

        //argpayClass apiFunctions = new argpayClass();


        string Response = string.Empty;

        apiFunctions.PagamentoTCP(0,500,ref members.Ped_ip,Convert.ToInt32(members.PedPort),ref members.DatiAgg,ref Response);

        log.Info("IP is " + members.PedPort + ".Response Received from Api is: " + Response);


    }
}

public class ParamIn
{
    public int Amount;

    public string DatiAgg;

    public string PedPort;

    public string Ped_ip;

    public string ip_listener;

    public string port_listener;

    public int tmo;

    public int PrintTicket;

    public int Advance;

    public ParamIn()
    {
        Amount = 0;

        DatiAgg = "";

        Ped_ip = "";

        PedPort ="";

        port_listener = "";

        ip_listener = "";

        tmo = 0;

        PrintTicket = 0;
    }


}

}

我尝试使用

CoInitializeEx(NULL, COINIT_MULTITHREADED); 
DLL主文件中的

,但没有成功。我也改变了这个但还是一样的行为

public CComObjectRootEx<CComSingleThreadModel> 

to  public CComObjectRootEx<CComMultiThreadModel>

有人知道为什么只有在第一个线程正在进行时才会调用dll的功能吗?

在c#中,线程是正确创建的。每个线程都完成工作,但不能完成其他任务。它必须等待。

1 个答案:

答案 0 :(得分:0)

如果您知道对象的实现是线程安全的,并且想告诉.NET,请在COM对象中实现IMarshal接口。

使用CoCreateFreeThreadedMarshaler创建封送处理程序,当.NET通过IMarshal调用请求QueryInterface接口时,返回封送处理程序。

如果您使用ATL来实现您的对象,请look at my answer以获取更多信息。