C# R6025纯虚函数调用

C# R6025纯虚函数调用,c#,pure-virtual,rtd,r6025,C#,Pure Virtual,Rtd,R6025,我在使用ThinkOrSwim的定制c#RTD客户端时,随机出现R6025纯虚拟函数调用错误 我怎样才能a)调试它,找出哪里出了问题,b)修复它 当windows弹出消息框说有错误时,代码会在后台继续运行,不会引发异常。但当我在消息框上单击OK时,windows会关闭应用程序 以下是请求RTD数据的代码片段: var tosClassId = new Guid(Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Tos.RTD\CLSI

我在使用ThinkOrSwim的定制c#RTD客户端时,随机出现R6025纯虚拟函数调用错误

我怎样才能a)调试它,找出哪里出了问题,b)修复它

当windows弹出消息框说有错误时,代码会在后台继续运行,不会引发异常。但当我在消息框上单击OK时,windows会关闭应用程序

以下是请求RTD数据的代码片段:

var tosClassId = new Guid(Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Tos.RTD\CLSID", "", null).ToString());
var rtdClient = new RtdClient(tosClassId);

var date = DateTime.Now.Date;
foreach (var futureSymbol in futureSymbols) {
    var settlement = GetDouble(rtdClient, futureSymbol, "CLOSE");
    yield return new TOSEODDataPoint {
        Date = date,
        Settlement = settlement,
    };
}

static double GetDouble(IRtdClient client, string symbol, string topic) {
    object value;
    if (client.GetValue(TimeSpan.FromSeconds(3), out value, topic, symbol)) {
        try { return double.Parse(value.ToString()); } catch { return 0; }
    }
    return 0;
}
以下是RTD客户端实现:

// Inspired by http://awkwardcoder.com/2014/01/24/excel-rtd-client-in-c/

public interface IRtdClient {
    bool GetValue(TimeSpan timeout, out object value, params object[] args);
}

public class RtdClient : IRtdClient {

    readonly Guid ServerId;
    static readonly Dictionary<Guid, IRtdServer> servers = new Dictionary<Guid, IRtdServer>();
    static readonly Dictionary<Guid, int> topicIds = new Dictionary<Guid, int>();

    public RtdClient(Guid serverId) {
        ServerId = serverId;
    }

    public bool GetValue(TimeSpan timeout, out object value, params object[] args) {

        value = null;
        var server = GetRtdServer();
        var topicId = GetTopicId();

        var sw = Stopwatch.StartNew();

        try {
            server.ConnectData(topicId, args, true);
            while (sw.Elapsed < timeout) {
                var alive = server.Heartbeat();
                if (alive != 1) {
                    // TODO: What should be done here?
                    return false;
                }
                var refresh = server.RefreshData(1);
                if (refresh.Length > 0) {
                    if (refresh[0, 0].ToString() == topicId.ToString()) {
                        value = refresh[1, 0];
                        return true;
                    }
                }
                Thread.Sleep(20);
            }
        } catch (Exception ex) {
            // TODO: Log exception
            return false;
        } finally {
            server.DisconnectData(topicId);
            sw.Stop();
        }
        return false;
    }

    IRtdServer GetRtdServer() {
        IRtdServer server;
        if (!servers.TryGetValue(ServerId, out server)) {
            Type rtd = Type.GetTypeFromCLSID(ServerId);
            server = (IRtdServer)Activator.CreateInstance(rtd);
            servers[ServerId] = server;
        }
        return server;
    }

    int GetTopicId() {
        int topicId = 0;
        if (topicIds.TryGetValue(ServerId, out topicId)) {
            topicId++;
        }
        topicIds[ServerId] = topicId;
        return topicId;
    }
}

[ComImport, TypeLibType((short)0x1040), Guid("EC0E6191-DB51-11D3-8F3E-00C04F3651B8")]
public interface IRtdServer {
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(10)]
    int ServerStart([In, MarshalAs(UnmanagedType.Interface)] IRTDUpdateEvent callback);

    [return: MarshalAs(UnmanagedType.Struct)]
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(11)]
    object ConnectData([In] int topicId, [In, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)] ref object[] parameters, [In, Out] ref bool newValue);

    [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_VARIANT)]
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(12)]
    object[,] RefreshData([In, Out] ref int topicCount);

    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(13)]
    void DisconnectData([In] int topicId);

    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(14)]
    int Heartbeat();

    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(15)]
    void ServerTerminate();
}

[ComImport, TypeLibType((short)0x1040), Guid("A43788C1-D91B-11D3-8F39-00C04F3651B8")]
public interface IRTDUpdateEvent {
    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(10), PreserveSig]
    void UpdateNotify();

    [DispId(11)]
    int HeartbeatInterval {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(11)]
        get;
        [param: In]
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(11)]
        set;
    }

    [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(12)]
    void Disconnect();
}
//灵感来自http://awkwardcoder.com/2014/01/24/excel-rtd-client-in-c/
公共接口IRtdClient{
bool GetValue(TimeSpan超时、out对象值、params对象[]args);
}
公共类RtdClient:IRtdClient{
只读Guid服务器ID;
静态只读字典服务器=新建字典();
静态只读字典topicIds=新字典();
公共RTD客户端(Guid服务器ID){
ServerId=ServerId;
}
public bool GetValue(TimeSpan超时、out对象值、params对象[]args){
值=空;
var server=GetRtdServer();
var topicId=GetTopicId();
var sw=Stopwatch.StartNew();
试一试{
ConnectData(topicId,args,true);
同时(软件运行<超时){
var alive=server.Heartbeat();
如果(活动!=1){
//TODO:这里应该做什么?
返回false;
}
var refresh=server.RefreshData(1);
如果(refresh.Length>0){
if(刷新[0,0].ToString()==topicId.ToString()){
值=刷新[1,0];
返回true;
}
}
睡眠(20);
}
}捕获(例外情况除外){
//TODO:日志异常
返回false;
}最后{
服务器。断开数据连接(topicId);
sw.Stop();
}
返回false;
}
IRtdServer GetRtdServer(){
IRtdServer;
如果(!servers.TryGetValue(ServerId,out server)){
类型rtd=Type.GetTypeFromCLSID(服务器ID);
server=(IRtdServer)Activator.CreateInstance(rtd);
服务器[ServerId]=服务器;
}
返回服务器;
}
int GetTopicId(){
int-topicId=0;
if(topicIds.TryGetValue(ServerId,out-topicId)){
topicId++;
}
topicIds[ServerId]=topicId;
返回topicId;
}
}
[ComImport,TypeLibType((短)0x1040),Guid(“EC0E6191-DB51-11D3-8F3E-00C04F3651B8”)]
公共接口IRtdServer{
[MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(10)]
int ServerStart([In,marshallas(UnmanagedType.Interface)]IRTDUpdateEvent回调);
[返回:MarshalAs(UnmanagedType.Struct)]
[MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(11)]
对象ConnectData([In]int-topicId,[In,marshallas(UnmanagedType.SafeArray,SafeArraySubType=VarEnum.VT_VARIANT)]ref-object[]参数,[In,Out]ref-bool-newValue);
[返回:MarshalAs(UnmanagedType.SafeArray,SafeArraySubType=VarEnum.VT_VARIANT)]
[MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(12)]
对象[,]刷新数据([In,Out]ref int topicCount);
[MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(13)]
void DisconnectData([In]int-topicId);
[MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(14)]
int Heartbeat();
[MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(15)]
void ServerTerminate();
}
[ComImport,TypeLibType((短)0x1040),Guid(“A43788C1-D91B-11D3-8F39-00C04F3651B8”)]
公共接口IRTDUpdateEvent{
[MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(10),PreserveSig]
void UpdateNotify();
[附表(11)]
心脏跳动间隔{
[MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(11)]
得到;
[参数:In]
[MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(11)]
设置
}
[MethodImpl(MethodImplOptions.InternalCall,MethodCodeType=MethodCodeType.Runtime),DispId(12)]
无效断开连接();
}
以下是我如何通过减少失败次数来“修复”这个问题。。。现在有一个200ms的初始延迟,该延迟使循环的每次迭代都加倍。(我仍在寻找真正的解决方案)

public bool GetValue(TimeSpan超时、out对象值、params对象[]args){
值=空;
var server=GetRtdServer();
var topicId=GetTopicId();
var sw=Stopwatch.StartNew();
无功延迟=200;
试一试{
ConnectData(topicId,args,true);
同时(软件运行<超时){
睡眠(延迟);
延迟*=2;
var alive=server.Heartbeat();
如果(活动!=1){
//TODO:这里应该做什么?
返回false;
}
var refresh=server.RefreshData(1);
如果(refresh.Length>0){
if(刷新[0,0].ToString()==topicId.ToString()){
值=刷新[1,0];
返回true;
}
}
}
}捕获(例外情况除外){
//TODO:日志异常
返回false;
}最后{
服务器。断开数据连接(topicId);
sw.Stop();
}
返回false;
}

调用服务器时是否发生错误?H
    public bool GetValue(TimeSpan timeout, out object value, params object[] args) {

        value = null;
        var server = GetRtdServer();
        var topicId = GetTopicId();

        var sw = Stopwatch.StartNew();
        var delay = 200;

        try {
            server.ConnectData(topicId, args, true);
            while (sw.Elapsed < timeout) {
                Thread.Sleep(delay);
                delay *= 2;
                var alive = server.Heartbeat();
                if (alive != 1) {
                    // TODO: What should be done here?
                    return false;
                }
                var refresh = server.RefreshData(1);
                if (refresh.Length > 0) {
                    if (refresh[0, 0].ToString() == topicId.ToString()) {
                        value = refresh[1, 0];
                        return true;
                    }
                }
            }
        } catch (Exception ex) {
            // TODO: Log exception
            return false;
        } finally {
            server.DisconnectData(topicId);
            sw.Stop();
        }
        return false;
    }