R6025纯虚函数调用

当我为ThinkOrSwim使用这个自定义c#RTD客户端时,我随机获得随机R6025 – 纯虚函数调用错误。

我怎样才能a)调试它以找出出错的地方,并且b)修复它?

当Windows弹出消息框表示存在错误时,代码将继续在后台运行,并且不会抛出任何exception。 但是当我在消息框中单击“确定”时,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 servers = new Dictionary(); static readonly Dictionary topicIds = new Dictionary(); 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  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(); } 

以下是我通过减少故障来“修复”问题的方法……现在有一个200ms的初始延迟,并且延迟每次迭代都会加倍。 (我还在寻找真正的解决方案)

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