Как обновить пользовательский интерфейс из другого потока, работающего в другом классе

В настоящее время я пишу свою первую программу на C#, и я совсем новичок в этом языке (до сих пор работал только с 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);
        }
    }
}

Я был бы очень признателен, если бы у кого-то было простое объяснение, как обновить пользовательский интерфейс изнутри метода тестирования. Поскольку я новичок в C # и объектно-ориентированном программировании, слишком сложные ответы я, скорее всего, не пойму, но я сделаю все возможное.

Кроме того, если у кого-то есть идея получше (может быть, с помощью backgroundworker или чего-то еще), я готов ее увидеть.

38
задан vulkanino 7 March 2012 в 13:43
поделиться