В общем есть цикл, в нём что-то параллельно делается, и при определённых условиях нужно его остановить, и что-то на форме занести в текстбоксы, после чего программа считывает эти текстбоксы.
Нашёл что-то про ManualResetEventSlim, но он блочит все потоки, и с формой не поработаешь (висит).
Наколхозил в таком виде (в том месте, где нужно остановить):
ManualResetEventSlim mres.Reset();
if(MainProcID == Thread.CurrentThread.ManagedThreadId) //MainProcID получаю при
// инициализации формы
{
while (!CF) //булевый флаг для бесконечного цикла, пока кнопку не
//нажму
{
Application.DoEvents();
}
//тут что-нибудь делаю
mres.set();
}
else
mres.Wait();
Но как это покрасивее сделать? Тут ещё, полагаю, будут проблемы, если 2 потока решат её остановить - непредсказуемый результат - надо ещё флагами защищаться. Ну, соответственно - потом надо запустить по нажатию кнопки.
Весь цикл
Parallel.ForEach(DRList, new ParallelOptions { MaxDegreeOfParallelism = 5 }, DR =>
{
ClassSrz srz1 = new ClassSrz("SRZ-01", DBSelected);
i++;
//reportProgress(i * 100 / Col);
int C = srz1.ExecuteNonQueryR("update ZAGS_PARENT_INFO set PID=" + DR["ID"].ToString() +
" where DR=" + strToSQL(DR["DR"].ToString(), date: true, last: true) +
" and docn=" + strToSQL(DR["DOCN"].ToString(), last: true) +
" and DOCS=" + strToSQL(DR["DOCS"].ToString(), last: true) +
" and docdt=" + strToSQL(DR["DOCDT"].ToString(), date: true, last: true) +
" and FAM_NEW=" + strToSQL(DR["FAM"].ToString(), last: true) +
" and IM_NEW=" + strToSQL(DR["IM"].ToString(), last: true) +
" and OT_NEW=" + strToSQL(DR["OT"].ToString(), last: true) +
" and PID is null"
);
int CWNew = srz1.ExecuteNonQueryR("update ZAGS_BRAK_INFO set PID_W_NEW=" + DR["ID"].ToString() +
" where DR_W=" + strToSQL(DR["DR"].ToString(), date: true, last: true) +
" and docn_W=" + strToSQL(DR["DOCN"].ToString(), last: true) +
" and DOCS_W=" + strToSQL(DR["DOCS"].ToString(), last: true) +
" and docdt_W=" + strToSQL(DR["DOCDT"].ToString(), date: true, last: true) +
" and FAM_W_NEW=" + strToSQL(DR["FAM"].ToString(), last: true) +
" and IM_W=" + strToSQL(DR["IM"].ToString(), last: true) +
" and OT_W=" + strToSQL(DR["OT"].ToString(), last: true) +
" and PID_W_NEW is null"
);
int CMNew = srz1.ExecuteNonQueryR("update ZAGS_BRAK_INFO set PID_M_NEW=" + DR["ID"].ToString() +
" where DR_M=" + strToSQL(DR["DR"].ToString(), date: true, last: true) +
" and docn_M=" + strToSQL(DR["DOCN"].ToString(), last: true) +
" and DOCS_M=" + strToSQL(DR["DOCS"].ToString(), last: true) +
" and docdt_M=" + strToSQL(DR["DOCDT"].ToString(), date: true, last: true) +
" and FAM_M_NEW=" + strToSQL(DR["FAM"].ToString(), last: true) +
" and IM_M=" + strToSQL(DR["IM"].ToString(), last: true) +
" and OT_M=" + strToSQL(DR["OT"].ToString(), last: true) +
" and PID_M_NEW is null"
);
int CMOld = srz1.ExecuteNonQueryR("update ZAGS_BRAK_INFO set PID_M_OLD=" + DR["ID"].ToString() +
" where DR_M=" + strToSQL(DR["DR"].ToString(), date: true, last: true) +
" and docn_M=" + strToSQL(DR["DOCN"].ToString(), last: true) +
" and DOCS_M=" + strToSQL(DR["DOCS"].ToString(), last: true) +
" and docdt_M=" + strToSQL(DR["DOCDT"].ToString(), date: true, last: true) +
" and FAM_M_OLD=" + strToSQL(DR["FAM"].ToString(), last: true) +
" and IM_M=" + strToSQL(DR["IM"].ToString(), last: true) +
" and OT_M=" + strToSQL(DR["OT"].ToString(), last: true) +
" and PID_M_OLD is null"
);
int CWOld = srz1.ExecuteNonQueryR("update ZAGS_BRAK_INFO set PID_W_OLD=" + DR["ID"].ToString() +
" where DR_W=" + strToSQL(DR["DR"].ToString(), date: true, last: true) +
" and docn_W=" + strToSQL(DR["DOCN"].ToString(), last: true) +
" and DOCS_W=" + strToSQL(DR["DOCS"].ToString(), last: true) +
" and docdt_W=" + strToSQL(DR["DOCDT"].ToString(), date: true, last: true) +
" and FAM_W_OLD=" + strToSQL(DR["FAM"].ToString(), last: true) +
" and IM_W=" + strToSQL(DR["IM"].ToString(), last: true) +
" and OT_W=" + strToSQL(DR["OT"].ToString(), last: true) +
" and PID_W_OLD is null"
);
if (ColPar == 1)
{
mres.Reset();
if (MainProcID == Thread.CurrentThread.ManagedThreadId)
{
CF = false;
while (!CF)
{
Application.DoEvents();
}
}
else
mres.Wait();
}
BeginInvoke((Action)(() =>
{
pB1.Value = i; ColPar += C; ColBracWNew += CWNew; ColBracMNew += CMNew;
ColBracWOld += CWOld; ColBracMOld += CMOld;
//Останавливаем для выбора
}));
Application.DoEvents();
// Thread.Sleep(100);
}
);
Вот кнопка
private void ChangeFlag_Click(object sender, EventArgs e)
{
CF = true;
if (mres.IsSet)
mres.Reset();
else
mres.Set();
}
P.S. условие if (ColPar == 1)
просто для теста поставил пока
public partial class MainForm : Form
{
//источник токена отмены
private CancellationTokenSource _cts;
public MainForm()
{
InitializeComponent();
StartPosition = FormStartPosition.CenterScreen;
Text = "Пример";
_buttonCancel.Click += ButtonCancel_Click;
_buttonStart.Click += ButtonStart_Click;
}
private async void ButtonStart_Click(object sender, EventArgs e)
{
//готовим запуск
_textBoxOutput.Text = String.Empty;
_buttonCancel.Enabled = true;
_buttonStart.Enabled = false;
//собираем данные
var inputs = new string[] { _textBoxFirst.Text, _textBoxSecond.Text, _textBoxThird.Text };
//новый источник токена отмены
_cts = new CancellationTokenSource();
//опции для параллельного запуска
var po = new ParallelOptions();
//передаем токен отмены
po.CancellationToken = _cts.Token;
try
{
//запускаем задачей чтоб освободить UI
await Task.Run(() => RunParallel(inputs, po));
}
finally
{
//настраиваем по окончании вычисления
_buttonCancel.Enabled = false;
_buttonStart.Enabled = true;
_cts.Dispose();
}
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
//отправляем запрос на отмену
_cts.Cancel();
}
private void RunParallel(string[] inputs, ParallelOptions po)
{
try
{
Parallel.ForEach(inputs, po, (string t, ParallelLoopState state) =>
{
//если был запрос на отмену, останавливаем цикл
if (po.CancellationToken.IsCancellationRequested)
{
state.Stop();
}
//получаем данные
var text = GetText(t, po.CancellationToken) + Environment.NewLine;
//отображаем данные
this.BeginInvoke((Action)(() => _textBoxOutput.Text += text));
});
}
catch (Exception ex)
{
this.BeginInvoke((Action)(() => _textBoxOutput.Text += ex.Message));
}
}
//метод, который типа что-то вычисляет
private string GetText(string t, CancellationToken cancellationToken)
{
var result = String.Empty;
for (int i = 0; i < 5; i++)
{
//бросаем исключение в случае отмены
cancellationToken.ThrowIfCancellationRequested();
Thread.Sleep(500);
result += $"{t}[{i}]";
}
return result;
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Подскажите как будет выглядеть эти два кусочка кода на c#?
при написании модульного теста возникает ошибка "object не содержит определения для qwerty"
Подскажите в чем может быть проблема, вылетает ошибка при миграции на добавление связи между таблицами