Я попытался изо всех сил создать пользовательский цикл while, но закончился тщетно. Неужели кому-то удалось создать пользовательский цикл while в NANT?Создание пользовательского цикла WHILE в NANT
ответ
Без дополнительной информации, есть учебное пособие по созданию пользовательской задачи NAnt here.
Одна хорошая вещь о статье автор предлагает 2 средства отладки пользовательской задачи:
Копирование сборки (и PDB-файл) в папку бин NAnt. Откройте свое решение в Visual Studio, которое содержит источник вашей задачи. Поместите свои контрольные точки. Перейдите к свойствам проекта и откройте страницу «Отладка». Измените режим Debug на Program и Start Application на путь к исполняемому файлу NAnt (например, C: \ Program Files \ NAnt \ bin \ NAnt.exe). Затем задайте аргументы рабочей директории и/или командной строки, чтобы NAnt собирал ваш файл сборки. Нажмите «Бег» и отпустите.
Place System.Diagnostics.Debbugger.Break(); в вашем коде перед строкой, которую вы хотите разбить. Повторно скомпилируйте проект и скопируйте сборку (и pdb) в каталог NAnt bin. Когда вы запускаете свой скрипт NAnt, вы должны получить всплывающее окно с просьбой выбрать отладчик.
Существует еще один учебник here.
С другой стороны, можете ли вы выразить свою проблему с точки зрения foreach?
Я создал пользовательскую задачу самостоятельно. Но, похоже, есть некоторые проблемы с использованием вложенных циклов в NANT.
В основном я пытаюсь использовать вложенный цикл. Цикл while внутри foreach или foreach внутри другого foreach. Но в обоих случаях цикл выполняет текущую цель & цель, из которой вызывается текущая цель для каждой итерации, а не тела внутри второго цикла.
С уважением
Sarathy
Вы опубликовали бы исчерпывающий минималистский пример кода и задач NAnt, которые могут продемонстрировать проблему? – JeffH
Вы можете создать пользовательскую задачу:
<target name="sample">
<property name="foo.value" value="0"/>
<while property="foo.value" equals="0">
<do>
<echo message="${foo.value}"/>
<property name="foo.value" value="${int::parse(foo.value) + 1}"/>
</do>
</while>
</target>
<script language="C#" prefix="directory">
<code>
<![CDATA[
[TaskName("while")]
public class WhileTask : TaskContainer
{
private TaskContainer _doStuff;
private string _propertyName;
private string _equals;
private string _notEquals;
[BuildElement("do")]
public TaskContainer StuffToDo
{
get
{
return this._doStuff;
}
set
{
this._doStuff = value;
}
}
[TaskAttribute("property")]
public string PropertyName
{
get
{
return this._propertyName;
}
set
{
this._propertyName = value;
}
}
[TaskAttribute("equals")]
public string Equals
{
get
{
return this._equals;
}
set
{
this._equals = value;
}
}
[TaskAttribute("notequals")]
public string NotEquals
{
get
{
return this._notEquals;
}
set
{
this._notEquals = value;
}
}
protected override void ExecuteTask()
{
while (this.IsTrue())
{
this._doStuff.Execute();
}
}
private bool IsTrue()
{
if (!string.IsNullOrEmpty(this.Equals))
{
return this.Properties[this.PropertyName] == this.Equals;
}
return this.Properties[this.PropertyName] != this.NotEquals;
}
}
]]>
</code>
</script>
Там довольно много способов вы можете сделать это. Я написал что-то похожее на Cao, которое вызывает свойство true, поэтому условие может быть таким сложным, как вам нравится, и если оно сделано динамически, значение оценивается каждым циклом, который удобен, когда вы вызываете функции, например. для проверки файла существует. Я также добавил простой перерыв и продолжение контроля. Он также может быть запущен как бесконечный цикл без атрибутов, которые могут быть полезны, когда вы хотите, чтобы многие условия выходили (в этом случае используйте «if» с break/continue или - в моем случае - я хотел запустить задачу до тех пор, пока он исключается, а затем обрабатывается с помощью failonerror или блока trycatch.
Вот немного Nant скрипт, который показывает два способа отсчета от 10:
<property name="greaterthanzero" value="${int::parse(count) > 0}" dynamic="true"/>
<property name="count" value="10" />
<while propertytrue="greaterthanzero" >
<echo>CountDown = ${count}</echo>
<property name="count" value="${int::parse(count) - 1}" />
</while>
<property name="count" value="10" />
<while>
<if test="${int::parse(count) > 0}" >
<echo>CountDown = ${count}</echo>
<property name="count" value="${int::parse(count) - 1}" />
<continue/>
</if>
<break/>
</while>
А вот реальный пример мира я использую, чтобы ждать, пока файл блокировки не будет удален:
<property name="count" value="0" />
<property name="lockfileexists" value="${file::exists(lockfile)}" dynamic="true"/>
<while propertytrue="lockfileexists" >
<sleep seconds="1" />
<property name="count" value="${int::parse(count) + 1}" />
<if test="${count == '15'}" >
<echo>Timed out after 15 seconds</echo>
<break/>
</if>
</while>
Вот код задачи:
<script language="C#" prefix="loops">
<code>
<![CDATA[
public class LoopBreakException : Exception {}
public class LoopContinueException : Exception {}
[TaskName("break")]
public class BreakTask : Task
{
protected override void ExecuteTask()
{
throw new LoopBreakException();
}
}
[TaskName("continue")]
public class ContinueTask : Task
{
protected override void ExecuteTask()
{
throw new LoopContinueException();
}
}
[TaskName("while")]
public class WhileTask : TaskContainer
{
[TaskAttribute("propertytrue")]
public string PropertyName { get; set; }
protected bool CheckCondition()
{
if (!string.IsNullOrEmpty(PropertyName))
{
try
{
return bool.Parse(Properties[PropertyName]);
}
catch (Exception ex)
{
throw new BuildException(string.Format("While Property '{0}' not found", PropertyName), Location);
}
}
//for infinite loops
return true;
}
protected override void ExecuteTask()
{
while (CheckCondition())
{
try
{
ExecuteChildTasks();
}
catch (LoopContinueException)
{
continue;
}
catch (LoopBreakException)
{
break;
}
}
}
}
]]>
</code>
Вот еще один пример простой, но эффективной версии цикла while, реализованной в NAnt.
<?xml version="1.0"?>
<project name="whiletask" xmlns="http://tempuri.org/nant-donotuse.xsd">
<script language="C#" prefix="loop">
<code>
<![CDATA[
/// <summary>
/// A while loop task. Will continuelly execute the task while the <c>test</c> is <c>empty</c>
/// or evalutes to <c>true</c>.
/// </summary>
[TaskName("while")]
public class WhileTask : TaskContainer
{
private string _test;
private TaskContainer _childTasks;
/// <summary>
/// The expression to test each iteration. If empty, then always evalutes to true (i.e. infinite loop.)
/// </summary>
[TaskAttribute("test", ExpandProperties = false)]
public string Test
{
get { return _test; }
set { _test = NAnt.Core.Util.StringUtils.ConvertEmptyToNull(value); }
}
/// <summary>
/// Superficial to ensure the XML schema is rendered correctly for this task. It will get executed
/// if tasks exist within it.
/// </summary>
[BuildElement("do")]
public TaskContainer ChildTasks
{
get { return _childTasks; }
set { _childTasks = value; }
}
/// <summary>
/// Executes the while loop while the <c>test</c> evalutes to true or <c>test</c> is empty.
/// </summary>
protected override void ExecuteTask()
{
while (this.Test == null
|| bool.Parse(Project.ExpandProperties(this.Test, this.Location)))
{
if (this._childTasks != null)
{
this._childTasks.Execute();
}
else
{
base.ExecuteTask();
}
}
}
}
]]>
</code>
</script>
<property name="i" value="0" />
<while test="${int::parse(i) <= 10}">
<echo message="${i}" />
<property name="i" value="${int::parse(i)+1}" />
</while>
</project>
глядя на список доступных в данный момент задач для NAnt, это выглядит как пока больше не поддерживается (http://nant.sourceforge.net/release/latest/help/tasks/)
Так что я думаю, что самый простой и эффективный способ, как сделать пользовательский, а цикл - рекурсия.
Так, например, что-то вроде этого:
<property name="count" value="120" />
<target name="wait">
<if test="${int::parse(count) > 0}" >
<property name="count" value="${int::parse(count) - 1}" />
<call target="wait"/>
</if>
</target>
С уважением,
Marek
Вот один из способов написания цикла WHILE в NAnt, без каких-либо пользовательских задач или script
элемента, используя failonerror="false"
на петле foreach
.
<property name="n" value="10000" /><!-- this would be inefficient if "n" is very large -->
<property name="i" value="0" />
<foreach item="String" in="${string::pad-right(' ', int::parse(n), ',')}" delim="," property="val" failonerror="false" >
<if test="${int::parse(i) > 3}"><!-- put our exit condition here -->
<fail message="condition met, exit loop early" />
</if>
<echo message="i: ${i}" />
<property name="i" value="${int::parse(i) + 1}" />
</foreach>
Результат выполнения цикла WHILE выше выглядит следующим образом. Следует отметить, что в связи с failonerror="false"
fail
вызов не завершает сценарий:
[echo] i: 0
[echo] i: 1
[echo] i: 2
[echo] i: 3
[foreach] myscript.nant(24,18):
[foreach] condition met, exit loop early
BUILD SUCCEEDED - 1 non-fatal error(s), 0 warning(s)
I на основе цикл WHILE выше о том, как я построить цикл, который является немного упрощенной версией кода выше:
<property name="n" value="5" />
<property name="i" value="0" />
<foreach item="String" in="${string::pad-right(' ', int::parse(n), ',')}" delim="," property="val" >
<echo message="i: ${i}" />
<property name="i" value="${int::parse(i) + 1}" /> <!-- increment "i" -->
</foreach>
выход из цикла FOR выглядит следующим образом:
[echo] i: 0
[echo] i: 1
[echo] i: 2
[echo] i: 3
[echo] i: 4
BUILD SUCCEEDED
Я включил код цикла FOR, так как кто-то, кто посещает этот вопрос, может искать такую вещь. – Boinst
- 1. Создание файлов в bash из пользовательского ввода и цикла while
- 2. Создание цикла while в Python
- 3. Создание цикла while для игры
- 4. для цикла/while для чтения пользовательского ввода
- 5. Создание асинхронного цикла while в узлеJS
- 6. Создание словаря из цикла while (Python)
- 7. Создание массива идентификаторов из цикла while
- 8. Возможно ли создание свойств MVVM с использованием цикла while/while?
- 9. Создание экземпляров объектов с использованием цикла while
- 10. Преобразование цикла while в цикл while while
- 11. Создание связанного списка с использованием цикла while
- 12. PHP для цикла while while
- 13. Время выполнения цикла while while
- 14. Цикл While внутри цикла while while - SQL
- 15. Преобразование цикла do-while в цикл while
- 16. Как ускорить создание Nant Builds?
- 17. Создание субпроектов с использованием NANT
- 18. Создание WPF-приложения с NAnt
- 19. для цикла внутри цикла while
- 20. Android: обновление пользовательского интерфейса от адаптера внутри цикла while
- 21. Создание цикла while, который вставляет json-данные в sqlite (Android)
- 22. Создание простого меню с использованием цикла while в C++
- 23. Создание JSON из цикла while и foreach в php
- 24. NAnt <msbuild> пользовательского каталог вывода
- 25. Создание сложных условий набора файлов в Nant
- 26. Как получить данные из цикла while внутри цикла while
- 27. JOptionPane внутри цикла while, показывающего после цикла while, завершается
- 28. Завершение бесконечного цикла while
- 29. sed внутри цикла while
- 30. Остановка цикла while php
Можете ли вы описать проблему, которую вы пытаетесь решить с помощью цикла в то время? Возможно, другой способ. –