Я написал программу на C# Windows Forms для сохранения файлов в MATLAB.
Функция сохранения данных в MATLAB выполняется слишком долго, поэтому я решил использовать индикаторы выполнения для отображения пользователь, сколько времени потребуется для завершения процесса.
Я прилагаю свой код. В некоторых случаях он работает нормально, но в некоторых других случаях я получаю сообщение об ошибке:
System.IndexOutOfRangeException: 'Вероятное состояние гонки ввода-вывода обнаружено при копировании памяти. Пакет ввода-вывода по умолчанию не является потокобезопасным. В многопоточных приложениях доступ к потоку должен осуществляться потокобезопасным способом, например, с помощью потокобезопасной оболочки, возвращаемой методами TextReader или TextWriter Synchronized. Это также относится к таким классам, как StreamWriter и StreamReader.'
Я хочу, чтобы основная функция находилась в основном потоке, а индикатор выполнения обновлялся в другом потоке. , и, конечно, я хочу, чтобы файлы сохранялись один за другим, а заполнение индикатора выполнения происходило один за другим.
Действительно, я хочу избежать многопоточности, поскольку вся программа написана в одном потоке таким образом, просто создайте еще один поток для обновления каждого прогресса стоимость бара. Ниже мой код. Я рад вашей огромной помощи.
public class SaveToMatlab
{
ProgressBar progressBar = new ProgressBar();
private void BtnSaveToMatlab_Click(object sender, EventArgs e)
{
ResetProgressBars();
if (!backgroundWorker.IsBusy)
{
backgroundWorker.RunWorkerAsync();
}
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < tableLayoutPanel.Controls.Count; i++)
{
var flp = tableLayoutPanel.Controls as FlowLayoutPanel;
if (flp != null && flp.Controls.OfType().Any(x => x.Checked))
{
progressBar = flp.Controls.OfType().FirstOrDefault();
if (progressBar != null)
{
var directory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MatlabOutput");
fileList.SaveLogToMatWorkSpace(Path.Combine(directory, $"matlab_{fileList.GetIdentifier()}.mat"), backgroundWorker);
}
}
}
}
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = progressBar.Value + e.ProgressPercentage > 100 ? 100 : progressBar.Value + e.ProgressPercentage;
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("Operation was canceled.");
}
else if (e.Error != null)
{
MessageBox.Show("An error occurred: " + e.Error.Message);
}
else
{
MessageBox.Show("Operation completed successfully.");
}
}
}
public class OtherClass
{
public void SaveLogToMatWorkSpace(string fileName, BackgroundWorker worker)
{
if (indices.Count > 0)
{
double increment = 100 / (double)(indices.Count - 1);
for (int i = 0; i < indices.Count; i++)
{
if (indices.Count > 0)
{
//... My code to save in MATLAB...
}
int progress = (int)Math.Ceiling(increment);
worker.ReportProgress(progress);
}
new MatFileWriter(fileName, mlList, true);
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... ent-thread
Обновление индикатора выполнения в другом потоке ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Winforms: обновление индикатора выполнения в форме из расчета на уровне доступа к данным
Anonymous » » в форуме C# - 0 Ответы
- 37 Просмотры
-
Последнее сообщение Anonymous
-