快速修复错误:System.AccessViolationException
本文关键字:System AccessViolationException 错误 | 更新日期: 2023-09-27 17:57:49
我有一个quickfix.net应用程序。我使用的是.net/c++版本的快速修复
有时我的应用程序抛出这个错误,而我无法用try-catch块捕获它。修复消息的长度约为3000。我不是每次都会犯这个错误。这是事件日志:
框架版本:v4.0.30319描述:进程已终止由于未处理的异常。异常信息:System.AccessViolationException堆栈:位于位于的System.String.ctor(SByte*)位于的QuickFix.Group.getField(QuickFix.StringField)onMessage(QuickFix44.MarketDataIncrementalRefresh,QuickFix.SessionID)QuickFix44.MessageCracker.crack(QuickFix.Message,QuickFix.SessionID)在QuickFix.MessageCracker.crack(QuickFix.MMessage,QuickFix.SessionID,QuickFix.BeginString)QuickFix.MessageCracker.crack(QuickFix.MMessage,QuickFix.SessionID)
在FixApplication.fromApp(QuickFix.Message,QuickFix.SessionID),位于.Application.fromApp(Application*,FIX.Message*,FIX.SessionID*)
抛出错误的行:
public override void onMessage(QuickFix44.MarketDataIncrementalRefresh msg, SessionID sessionID)
{
try
{
var mdReqId = new MDReqID();
if (msg.isSet(mdReqId))
msg.get(mdReqId);
var noMdEntries = new NoMDEntries();
if (msg.isSet(noMdEntries))
msg.get(noMdEntries);
int noMdEntriesInt;
if (Int32.TryParse(noMdEntries.ToString(), out noMdEntriesInt))
{
for (uint i = 1; i <= noMdEntriesInt; i++)
{
var group = new MarketDataIncrementalRefresh.NoMDEntries();
Group repeatedData;
if (msg.isSet(noMdEntries))
{
repeatedData = msg.getGroup(i, group);
var mdUpdateAction = new MDUpdateAction();
if (repeatedData.isSetField(mdUpdateAction))
repeatedData.getField(mdUpdateAction);
var mdEntryType = new MDEntryType();
if (repeatedData.isSetField(mdEntryType))
repeatedData.getField(mdEntryType);
var symbol = new Symbol();
if (repeatedData.isSetField(symbol))
repeatedData.getField(symbol);
var mdEntryPx = new MDEntryPx();
if (repeatedData.isSetField(mdEntryPx))
repeatedData.getField(mdEntryPx);
var mdEntrySize = new MDEntrySize();
if (repeatedData.isSetField(mdEntrySize))
repeatedData.getField(mdEntrySize);
var numberOfOrders = new NumberOfOrders();
if (repeatedData.isSetField(numberOfOrders))
repeatedData.getField(numberOfOrders);
var mdEntryPositionNo = new MDEntryPositionNo();
if (repeatedData.isSetField(mdEntryPositionNo))
repeatedData.getField(mdEntryPositionNo);
var quoteCondition = new QuoteCondition();
if (repeatedData.isSetField(quoteCondition))
repeatedData.getField(quoteCondition);
var sysSymbolId = 0;
var mdEntryId = new MDEntryID();
if (repeatedData.isSetField(mdEntryId))
{
repeatedData.getField(mdEntryId);//THIS LINE THROWS ERROR
string strMdEntryId = mdEntryId.getValue();
}
//}
}
}
}
}
Functions.WriteDebugLog("OK");
}
catch (Win32Exception e)
{
Functions.WriteSystemLog("Ex Msg:" + e.ToString() + " Fix Msg : " + msg.ToString());
}
catch (Exception ex)
{
Functions.WriteSystemLog("Ex Msg:" + ex.ToString() + " Fix Msg : " + msg.ToString());
}
}
这是修复消息(你可以用这个在线工具解析它:http://fixloganalyzer.com/):
8=FIX.4.4|9=2254 |35=X|34=22198|49=*|50=*| 52=20140411-07:52:52.472|56=<strong|*>|262=139702702772472|268=42|279=1|278=2500|270=2.11636|271=35000000|276=A|290=1 |279=1 |278=25501|270=22.11626|271=2000000|276=A|290=2 |279=1 | 278=25502 |270=2.11616|271=3000000|276=A|290=3|279=1|278=25504|270=2.11596|271=7000000|276=A|290=5|279=1 |278=25510|270=2.1716|271=3500000 | 276=A | 290=1 | 279=1 | 278=25512 | 270=2.11736 | 271=5000000 | 276=A| 290=3 | 279=1| 278=255 13 | 270=2.11746 | 271=50000 | 276 | A | 290=4 | 279=1 | 278=25514 | 270=21756 | 271=6000000 | 276=阿| 290=5 | 279=1| 278=204 | 270=1.38947 | 271=1500000 | 276=A | 290=5 | 279=1 | 278=600 | 270=0.93834 | 271=1000000 | 276=一| 290=1| 279=1|278=601|270=0.983833|271=10000|276=A|290=2|279=1 |278=602|270=0.093832|271=1000000|276=A |290=3|279=1 | 278=603|270=0.93831|271=20000000|276=A|290=4|279=1|278=604|270=0.983821|271=2000000|276=A |290=5|279=1 |278=610|270=0.93839|271=10000000|276=A|290=1|279=1 | 278=611|270=0.93184|271=15000000|276=A |290=2 |279=1| 278=613|270=0.93384|271=35000000|276=A|290=4|279=1=5 | 279=1 | 278=2200 | 270=1.09337 | 271=1000000 | 276=A | 290=1 | 279=1 | 278=2201 | 270=1.0 9336 | 271=1000000 | 276=A | 290=2 | 279=1| 278=2203 | 270=109334|271=4000000|276=A|290=4|279=1|278=2204|270=1.099333|271=1000000|276=A |290=5|279=1=278=2211|270=1.03344|271=20000000|276=A|290=279=1|278=2014|270=1.9356|271=3000000|276=A|290=5|279=1 |278=119600|270=1.0182|271=10000000|276=A |290=2 |279=1 |278=19602 |270=1.0818 |271=1000000 |276=A |290=3 | 279=1 | 278=19603 | 270=1.08179 | 271=1000000 | 276=A | 290=4 | 279=1|278=19604 | 270=1.08178 | 271=1000000 | 276=A | 290=5 | 279=1 | 278=19612 | 270=1.0 8205 | 271=1000000 | 276=A | 290=3 | 279=1| 278=196 13 | 270=1 8206 | 271=1000000 | 276=A| 290=4 | 279=1| 278=19614 | 270=1.88216 | 271=2000000 | 276=A| 290=5 | 279=1 | 278=23600 | 270=1.51927 | 271=2000000 |276=A |290=2 |279=1 |278=23602 | 270=1.51925 | 271=1000000 | 276=A | 290=3 | 279=1 | 278=23603 | 270=1.5 1915 | 271=3000000 | 276=A|290=4|279=1|278=23604|270=1.51905|271=4000000|276=A|290=5|279=1 |278=223610|270=1.54195|271=1500000|276=A |290=1 |279=1 | 278=2311|270=1.55194|271=1000000|276=a2|279=1 |1|278=23612|270=1.5947|271=10000000|276=b|290=3|279=1| 278=26313|271=1.551957|271=20000000|276=A|290=4|279=1 270=1.51967 | 271=3000000 | 276=A | 290=5 | 10=142 |
这看起来是相关的。
这是关于Group对象中的一个竞赛条件,它在被引用之前收集垃圾。
您需要类似于gcnew
的内容:.Net垃圾收集
我修复了这个问题,制作了一个请求列表。示例:
public void RequisitarMarketData(List<String> _lstAtivo, String _mercado, String _id, SessionID sessionId)
{
QuickFix44.MarketDataRequest _marketDataRequest = new QuickFix44.MarketDataRequest();
_marketDataRequest.set(new MDReqID(_id));
_marketDataRequest.set(new SubscriptionRequestType('1'));
var anoMDEntryTypes = new QuickFix44.MarketDataRequest.NoMDEntryTypes();
var amdEntryType_bid = new MDEntryType('2');
anoMDEntryTypes.set(amdEntryType_bid);
_marketDataRequest.addGroup(anoMDEntryTypes);
_marketDataRequest.set(new MarketDepth(0));
foreach (String _ativo in _lstAtivo)
{
var relatedSymbol = new QuickFix44.MarketDataRequest.NoRelatedSym();
relatedSymbol.set(new Symbol(_ativo));
_marketDataRequest.addGroup(relatedSymbol);
}
var relatedSymbola = new QuickFix44.MarketDataRequest.NoRelatedSym();
relatedSymbola.set(new SecurityExchange(_mercado));
_marketDataRequest.addGroup(relatedSymbola);
//Send message
Session.sendToTarget(_marketDataRequest, sessionId);
}`