Цитата:
Сообщение от
gl00mie
А теперь запустите ваш код, дергающий xSession::xppCallStack(), в IL - и обломитесь...
Как-то некрасиво x++ себя ведет в этой ситуации.
Попробовал набросать метод замену. Расположил в классе Session.
X++:
/// <summary>
/// Splits the given String by the specified separator and returns the contents in a container.
/// GRD_Stuff_pkoz, Перенос "наработок" из 2009-й, pkoz, 22.11.2015
/// </summary>
/// <param name="_value">
/// The String value to be split.
/// </param>
/// <param name="_sep">
/// The separator.
/// </param>
/// <param name="_convertNumericToInt64">
/// A Boolean value that indicates whether to convert the value to an <c>int64</c> value; optional.
/// </param>
/// <param name="_unpackLineNumber">
/// A Boolean value that indicates whether to extract line number from stacktrace string _value; optional.
/// </param>
/// <returns>
/// A container, which has the String split by the specified separator.
/// </returns>
/// <remarks>
/// In the <paramref name="_convertNumericToInt64" /> parameter, a value of true indicates the returned
/// contents will be converted to an <c>int64</c> value if they only have numeric characters.A value of
/// false indicates that the returned values will not be converted to an <c>int64</c> value and String
/// values will always be returned. The default value of the <paramref name="_convertNumericToInt64" />
/// parameter is true.
/// </remarks>
static container stackLine2con(str _value, str 10 _sep = ',', boolean _convertNumericToInt64 = true, boolean _unpackLineNumber = false)
{
int length = strLen(_value);
int separatorLength = strLen(_sep);
int i = 1;
int j = strScan(_value, _sep, 1, length);
container ret;
void add2Ret(str _current)
{
if (_convertNumericToInt64 && (match('<:d+>', _current)))
{
ret += str2int64(_current);
}
else
{
ret += _current;
}
//GRD_Stuff_pkoz, Перенос "наработок" из 2009-й, pkoz, 22.11.2015 -->
if ( _unpackLineNumber )
{
ret += 0; // пока не реализовано
}
else
{
ret += 0;
}
//GRD_Stuff_pkoz, Перенос "наработок" из 2009-й, pkoz, 22.11.2015 <--
}
while (j)
{
add2Ret(subStr(_value, i, j-i));
i = j + separatorLength;
j = strScan(_value, _sep, i, length);
}
add2Ret(subStr(_value, i, length-i+1));
return ret;
}
/// </param>
/// <param name="_mode">
/// An Int value that indicates how to convert the value to container; optional.
/// </param>
/// <returns>
/// A container, which has the stack trace.
/// </returns>
/// <remarks>
///
/// </remarks>
client server public static container xppILCallStack(int _mode = 0)
{
str stack;
container ret;
// int startPos;
#define.delimiter(" at ")
;
if (!xSession::isCLRSession())
return xSession::xppCallStack();
new InteropPermission(InteropKind::ClrInterop).assert();
stack = System.Environment::get_StackTrace();
// startPos = strScan(stack, #delimiter, 1, 1000);
switch (_mode)
{
case 0 : // режим, похожий на обычный xSession::xppCallStack() только извлечение номеров строк не сделано
ret = [
(isRunningOnServer() ? "(S)" : "(C)") + "(CIL)", _mode
] +
Session::stackLine2con(stack, #delimiter, false, false);
break;
case 1 : // быстрый режим, чтобы не тратить процессорное время на обработку строк. Использующий код в дальнейшем сам обработает как надо - распакует и.т.п. А скорее всего просто проигнорирует.
ret = [
(isRunningOnServer() ? "(S)" : "(C)") + "(CIL)", _mode
] +
[stack, 0];
break;
}
return ret;
}
А потом подумалось - возможно это велосипед и я просто не нашел нужного кода в стандарте.
Кто как решает проблему получения стека вызовов при исполнении в p-code и CIL ?