调用C++/C#的CLI随时间变慢 我正在为C++库编写一个C++/CLI包装库。C++/CLI不是我的首选语言,但经过几次尝试之后,我成功地生成了一个可从C#使用的托管库

调用C++/C#的CLI随时间变慢 我正在为C++库编写一个C++/CLI包装库。C++/CLI不是我的首选语言,但经过几次尝试之后,我成功地生成了一个可从C#使用的托管库,c#,c++-cli,interop,C#,C++ Cli,Interop,问题是,随着时间的推移,调用函数的速度逐渐变慢。起初大约需要3-4毫秒(用秒表测量),然后逐渐增加到4000毫秒及以上 这些是相关的代码片段。请注意,我已经删除了名称空间,还合并了.cpp/.h文件以使其更易于阅读 Program.cs using (var session = new Session()) { Stopwatch stopWatch; var handle = session.Add(addParams); while (true) {

问题是,随着时间的推移,调用函数的速度逐渐变慢。起初大约需要3-4毫秒(用秒表测量),然后逐渐增加到4000毫秒及以上

这些是相关的代码片段。请注意,我已经删除了名称空间,还合并了.cpp/.h文件以使其更易于阅读

Program.cs

using (var session = new Session())
{
    Stopwatch stopWatch;
    var handle = session.Add(addParams);

    while (true)
    {
        stopWatch.StartNew();
        handle.GetStatus(); // This call is gradually getting slower.
        stopWatch.Stop();

        Console.WriteLine("{0}ms to get status.", stopWatch.ElapsedMilliseconds);

        Thread.Sleep(1000);
    }
}
Session.h

public ref class Session
{
private:
    void* _pointer;

    property libtorrent::session* Pointer
    {
        inline libtorrent::session* get()
        {
            return (libtorrent::session*)this->_pointer;
        }
    }

public:
    Session()
    {
        this->_pointer = new libtorrent::session();
    }

    TorrentHandle^ Add(AddTorrentParams ^addTorrentParams)
    {
        auto handle = this->Pointer->add_torrent(*addTorrentParams->Pointer);
        return gcnew TorrentHandle(handle);
    }
}
public ref class TorrentHandle
{
private:
    void* _pointer;

    property libtorrent::torrent_handle* Pointer
    {
        inline libtorrent::torrent_handle* get()
        {
            return (libtorrent::torrent_handle*)this->_pointer;
        }
    }

internal:
    TorrentHandle(libtorrent::torrent_handle const &handle)
    {
        this->_pointer = (void*) new libtorrent::torrent_handle(handle);
    }

public:
    TorrentStatus^ GetStatus()
    {
        return gcnew TorrentStatus(this->Pointer->status());
    }
}
public ref class TorrentStatus
{
private:
    void* _pointer;

    property libtorrent::torrent_status* Pointer
    {
        inline libtorrent::torrent_status* get()
        {
            return (libtorrent::torrent_status*)this->_pointer;
        }
    }

public:
    TorrentStatus(libtorrent::torrent_status &status)
    {
        this->_pointer = (void*)new libtorrent::torrent_status(status);
    }
}
TorrentHandle.h

public ref class Session
{
private:
    void* _pointer;

    property libtorrent::session* Pointer
    {
        inline libtorrent::session* get()
        {
            return (libtorrent::session*)this->_pointer;
        }
    }

public:
    Session()
    {
        this->_pointer = new libtorrent::session();
    }

    TorrentHandle^ Add(AddTorrentParams ^addTorrentParams)
    {
        auto handle = this->Pointer->add_torrent(*addTorrentParams->Pointer);
        return gcnew TorrentHandle(handle);
    }
}
public ref class TorrentHandle
{
private:
    void* _pointer;

    property libtorrent::torrent_handle* Pointer
    {
        inline libtorrent::torrent_handle* get()
        {
            return (libtorrent::torrent_handle*)this->_pointer;
        }
    }

internal:
    TorrentHandle(libtorrent::torrent_handle const &handle)
    {
        this->_pointer = (void*) new libtorrent::torrent_handle(handle);
    }

public:
    TorrentStatus^ GetStatus()
    {
        return gcnew TorrentStatus(this->Pointer->status());
    }
}
public ref class TorrentStatus
{
private:
    void* _pointer;

    property libtorrent::torrent_status* Pointer
    {
        inline libtorrent::torrent_status* get()
        {
            return (libtorrent::torrent_status*)this->_pointer;
        }
    }

public:
    TorrentStatus(libtorrent::torrent_status &status)
    {
        this->_pointer = (void*)new libtorrent::torrent_status(status);
    }
}
TorrentStatus.h

public ref class Session
{
private:
    void* _pointer;

    property libtorrent::session* Pointer
    {
        inline libtorrent::session* get()
        {
            return (libtorrent::session*)this->_pointer;
        }
    }

public:
    Session()
    {
        this->_pointer = new libtorrent::session();
    }

    TorrentHandle^ Add(AddTorrentParams ^addTorrentParams)
    {
        auto handle = this->Pointer->add_torrent(*addTorrentParams->Pointer);
        return gcnew TorrentHandle(handle);
    }
}
public ref class TorrentHandle
{
private:
    void* _pointer;

    property libtorrent::torrent_handle* Pointer
    {
        inline libtorrent::torrent_handle* get()
        {
            return (libtorrent::torrent_handle*)this->_pointer;
        }
    }

internal:
    TorrentHandle(libtorrent::torrent_handle const &handle)
    {
        this->_pointer = (void*) new libtorrent::torrent_handle(handle);
    }

public:
    TorrentStatus^ GetStatus()
    {
        return gcnew TorrentStatus(this->Pointer->status());
    }
}
public ref class TorrentStatus
{
private:
    void* _pointer;

    property libtorrent::torrent_status* Pointer
    {
        inline libtorrent::torrent_status* get()
        {
            return (libtorrent::torrent_status*)this->_pointer;
        }
    }

public:
    TorrentStatus(libtorrent::torrent_status &status)
    {
        this->_pointer = (void*)new libtorrent::torrent_status(status);
    }
}
我知道一些
void*
的铸造可能是不必要的,但我看不出它们是如何变得越来越慢的

正常运行时的输出

0ms to get status
0ms to get status
0ms to get status
1ms to get status
94ms to get status
18ms to get status
15ms to get status
68ms to get status
114ms to get status
112ms to get status
123ms to get status
130ms to get status
220ms to get status
210ms to get status
371ms to get status
277ms to get status
1152ms to get status
1081ms to get status
1384ms to get status
1424ms to get status
1387ms to get status
1520ms to get status
1471ms to get status
605ms to get status
1201ms to get status
1038ms to get status
1672ms to get status

是什么导致了这种减速行为?

我终于找到了问题所在。在发布模式下编译libtorrent时,一切正常运行。我猜在运行调试时会出现一些严重的断言。

您是否正在清理此代码之外的非托管资源?是的,在C++/CLI类析构函数中。您的调用不会变慢,您正在反复使用相同的
秒表
,请使用
秒表.StartNew()
而不是
启动
(或在每次迭代后重置)。我可以向您保证,调用速度正在变慢。我同意您的观点,秒表代码有一个错误-但是,挂钟时间正在增加。您在本机程序中有相同的行为吗?这并不能解释为什么代码会随着时间变慢。无论如何,Visual Studio有一个很好的分析器。继续,使用它。它也依赖于负载l-当libtorrent试图从torrents中获得尽可能多的速度时,速度减慢约为1-1.5秒。然后,这些断言导致了速度减慢。