В настоящее время я пишу свою первую программу на С#, и я чрезвычайно новичок в языке (используется только для работы с C до сих пор). Я провел много исследований, но все ответы были слишком общими, и я просто не мог заставить его работать.
Итак, вот моя (очень распространенная) проблема: У меня есть приложение WPF, которое берет входные данные из нескольких текстовых полей, заполненных пользователем, а затем использует это для проведения большого количества вычислений с ними. Они должны занять около 2-3 минут, поэтому я хотел бы обновить индикатор выполнения и текстовый блок, рассказывающий мне, каков текущий статус. Также мне нужно сохранить входы пользовательского интерфейса от пользователя и передать их в поток, поэтому у меня есть третий класс, который я использую для создания объекта и хотел бы передать этот объект в фоновый поток. Очевидно, что я буду запускать вычисления в другом потоке, поэтому пользовательский интерфейс не замерзает, но я не знаю, как обновлять пользовательский интерфейс, поскольку все методы расчета являются частью другого класса. После многого повторного поиска я думаю, что лучший способ пойти с будет использовать диспетчеров и TPL, а не фонового работника, но, честно говоря, я не уверен, как они работают, и после 20 часов проб и ошибок с другими ответами я решил спросить вопрос сам.
Здесь очень простая структура моей программы:
public partial class MainWindow : Window
{
public MainWindow()
{
Initialize Component();
}
private void startCalc(object sender, RoutedEventArgs e)
{
inputValues input = new inputValues();
calcClass calculations = new calcClass();
try
{
input.pota = Convert.ToDouble(aVar.Text);
input.potb = Convert.ToDouble(bVar.Text);
input.potc = Convert.ToDouble(cVar.Text);
input.potd = Convert.ToDouble(dVar.Text);
input.potf = Convert.ToDouble(fVar.Text);
input.potA = Convert.ToDouble(AVar.Text);
input.potB = Convert.ToDouble(BVar.Text);
input.initStart = Convert.ToDouble(initStart.Text);
input.initEnd = Convert.ToDouble(initEnd.Text);
input.inita = Convert.ToDouble(inita.Text);
input.initb = Convert.ToDouble(initb.Text);
input.initc = Convert.ToDouble(initb.Text);
}
catch
{
MessageBox.Show("Some input values are not of the expected Type.", "Wrong Input", MessageBoxButton.OK, MessageBoxImage.Error);
}
Thread calcthread = new Thread(new ParameterizedThreadStart(calculations.testMethod);
calcthread.Start(input);
}
public class inputValues
{
public double pota, potb, potc, potd, potf, potA, potB;
public double initStart, initEnd, inita, initb, initc;
}
public class calcClass
{
public void testmethod(inputValues input)
{
Thread.CurrentThread.Priority = ThreadPriority.Lowest;
int i;
//the input object will be used somehow, but that doesn't matter for my problem
for (i = 0; i < 1000; i++)
{
Thread.Sleep(10);
}
}
}
Я был бы очень признателен, если бы у кого-то было простое объяснение, как обновить интерфейс изнутри тестового метода. Поскольку я новичок в С# и объектно-ориентированном программировании, слишком сложные ответы, которые я, скорее всего, не пойму, я сделаю все возможное, хотя.
Кроме того, если у кого-то есть лучшая идея в целом (возможно, с использованием фонового работника или чего-то еще), я открыт для ее просмотра.