Рейтинг:
2
Richard Deeming
Что-то вроде этого:
CancellationTokenSource _cts = null;
private void BtnImoprt_Click(object sender, EventArgs e)
{
CancellationTokenSource newSource = new CancellationTokenSource();
CancellationTokenSource oldSource = Interlocked.Exchange(ref _cts, newSource);
if (oldSource != null)
{
oldSource.Cancel();
oldSource.Dispose();
}
Task.Run(() => Readtxt(newSource.Token), newSource.Token);
}
private void BtnCancel_Click(object sender, EventArgs e)
{
CancellationTokenSource oldSource = Interlocked.Exchange(ref _cts, null);
if (oldSource != null)
{
oldSource.Cancel();
oldSource.Dispose();
}
}
private async Task Readtxt(CancellationToken cancellationToken)
{
// Pass the cancellation token to any async methods that support it.
// Regularly check its IsCancellationRequested property, or call its ThrowIfCancellationRequested method.
}
Отмена в управляемых потоках | Microsoft Docs[
^]
Насколько это будет эффективно, будет зависеть от методов, которые вы используете в рамках проекта.
Readtxt
метод.
Member 11426986
Это метод Readtxt
пустота Readtxt()
{
строка ccte = txtFolderCTE.Text;
строку папку = нуль;
foreach (файловая система var в каталоге.Заражен(ccte, "*.в формате XML", searchoption указывает, нужно.AllDirectories))
{
FileInfo fi = новый FileInfo(файловая система);
каминью = Fi интернет.Полное имя;
пробовать
{
DirectXML dir = новый DirectXML();
dir.direcionarXML(папка, "");
}
catch (исключение m)
{
registerLog(м. Сообщение, папку);
}
}
}
Richard Deeming
Этот метод не имеет никакого смысла. Почему вы перечисляете каждый XML-файл в папке, когда вы ничего не делаете с этими файлами? Вы просто вызываете один и тот же метод с одними и теми же параметрами снова и снова.
Member 11426986
Нет "DirectXML dir = новый DirectXML ();
dir.direcionarXML(папка, ""); ", он будет считывать XML-файлы и сохранять собранную информацию в базу данных.
Richard Deeming
Нигде в коде, который вы показали, вы не используете переменную цикла. Вы просматриваете каждый XML-файл в папке и вызываете тот же метод с те же параметры по одному разу для каждого файла.
Ничего в твоей жизни нет. try..catch
блок использует fileSystem
, fi
, или caminho
.
Петля не имеет никакого смысла.
Member 11426986
В foreach он будет извлекать все XML - файлы из каталога, который вы ввели в переменную ccte. Это позволит получить полный путь к каждому XML-файлу и передать его классу, который будет читать XML.
Извините, произошла ошибка редактирования.
FileInfo fi = новый FileInfo (файловая система);
папка = Fi интернет.Полное имя;
пробовать
{
DirectXML dir = новый DirectXML ();
dir.directXML (папка, "");
}
catch (исключение m)
{
registerLog (м. Сообщение, папку);
}
Richard Deeming
Ну, если только вы не можете сделать то же самое. directXML
метод async
самое лучшее , что вы можете сделать, это:
private void Readtxt(CancellationToken cancellationToken)
{
string folderPath = txtFolderCTE.Text;
foreach (string filePath in Directory.EnumerateFiles(folderPath, "*.xml", SearchOption.AllDirectories))
{
cancellationToken.ThrowIfCancellationRequested();
try
{
DirectXML dir = new DirectXML();
dir.directXML(filePath, "");
}
catch (Exception ex)
{
registerLog(ex.Message, filePath);
}
}
}
Я бы также задался вопросом, Нужно ли создавать новый экземпляр вашего
DirectXML
класс для каждого файла; но это другой вопрос.
Member 11426986
Я постараюсь это сделать. Но это вызывает у меня сомнения. Как я могу увидеть, выполняется ли эта задача?
Richard Deeming
Упрощенно говоря, вы можете сохранить задачу, возвращенную из Task.Run
в поле и проверьте его состояние. Но может быть и лучший вариант, в зависимости от того, что вы на самом деле хотите сделать.
Member 11426986
Я использую ваш код и две задачи, а также добавил атрибут, чтобы различать, какую часть кода он будет выполнять. Как проверить с помощью таймера, когда задача закончена?
Это событие click button.
CancellationTokenSource newSource = новый CancellationTokenSource();
CancellationTokenSource oldSource = заблокирован.Биржа(ref _cts, newSource);
если (древнимисточником != нуль)
{
старый источник.Отменить();
старый источник.Располагать();
}
Task.Run(() => Readtxt(источник новостей.Маркер, "КТР"), newSource.Знак);
Task.Run(() => Readtxt(источник новостей.Токен, "НФЭ"), источник новостей.Знак);
Richard Deeming
Не беспокойтесь о таймере - просто используйте его async
код:
private void BtnCancel_Click(object sender, EventArgs e)
{
CancellationTokenSource newSource = new CancellationTokenSource();
CancellationTokenSource oldSource = Interlocked.Exchange(ref _cts, newSource);
if (oldSource != null)
{
oldSource.Cancel();
oldSource.Dispose();
}
// Discard the result:
_ = ExecuteImportAsync(newSource.Token);
}
private async Task ExecuteImportAsync(CancellationToken cancellationToken)
{
txtExecucaoPro.ForeColor = Color.FromArgb(0, 192, 0);
txtExecucaoPro.Text = "PROCESSO EM EXECUÇÃO";
try
{
Task cte = Task.Run(() => ExecutaLeitura(cancellationToken, "CTE"), cancellationToken);
Task nfe = Task.Run(() => ExecutaLeitura(cancellationToken, "NFE"), cancellationToken);
await Task.WhenAll(cte, nfe);
}
finally
{
txtExecucaoPro.Text = "PROCESSO COMPLETO";
}
}
Рассуждения, лежащие в основе части "отбросить результат", см.:
https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#timer-callbacks[
^]
Рейтинг:
0
George Swan
Вы не хотите создавать новое Tasks
и управляя ими напрямую, лучше вызвать метод, который возвращает Task
.
FileStream.ReadAsync()
возвращает Task
, поддерживает асинхронное считывание данных и может быть отменено.
Вы можете использовать его вот так.
private async Task<string>ReadFileAsync(string filePath,CancellationToken token)
{
byte[] byteArray;
FileStream fileStream = null;
try
{
fileStream = File.Open(filePath, FileMode.Open);
byteArray = new byte[fileStream.Length];
//this method call throws an OperationCancelledException if cancelled
//At this point control is returned to the UI thread
//until the method completes
await fileStream.ReadAsync(byteArray, 0, (int)fileStream.Length, token);
string text=Encoding.ASCII.GetString(byteArray);
return text;
}
finally
{
if (fileStream != null) fileStream.Dispose(); }
}
Вы можете начать загрузку данных в обработчике щелчка кнопки Пуск.
private CancellationTokenSource cts;
private async void Start(object sender, RoutedEventArgs e)
{
List<string> texts = new List<string>();
string filename = @"c:\Temp\Io.txt";
//disable the start button and enable the cancel button
cts = new CancellationTokenSource();
//Or, to test the cancellation process,
//make cts cancel itself after 20 millisecs
//cts = new CancellationTokenSource(20);
try
{
//simulate reading 100 files
for (int i = 0; i < 100; i++)
{
//pass in the cancellation token to the file read method
string text = await ReadFileAsync(filename, cts.Token);
texts.Add(text);
}
}
catch (OperationCanceledException )
{
//do something with the cancelled data
texts.Clear();
}
//......
}
Используйте обработчик щелчка кнопки отмены для отмены чтения файла.То
CancellationTokenSource
расходуется после отмены бронирования и не может быть использован повторно.
private void Cancel(object sender, RoutedEventArgs e)
{
if (cts != null) cts.Cancel();
}