Как вызвать То же событие Обработчик с несколькими объектами класса в форме Windows C # [дубликат]

К сожалению, во всех предыдущих ответах отсутствуют некоторые детали. Правильное решение немного громоздко, но это единственный способ сделать это правильно.

Вот как вы можете это сделать, точно сохраняя все детали и удобство использования:

  • решение в точности соответствует такие же, как изначально предназначенные
  • встроенные функции, все еще встроенные
  • пользователи A и B могут включать Ah и Bh в любом порядке

Создайте два файла: A_def.h, B_def.h. Они будут содержать только определения A и B:

// A_def.h
#ifndef A_DEF_H
#define A_DEF_H

class B;
class A
{
    int _val;
    B *_b;

public:
    A(int val);
    void SetB(B *b);
    void Print();
};
#endif

// B_def.h
#ifndef B_DEF_H
#define B_DEF_H

class A;
class B
{
    double _val;
    A* _a;

public:
    B(double val);
    void SetA(A *a);
    void Print();
};
#endif

И тогда, Ah и Bh будут содержать это:

// A.h
#ifndef A_H
#define A_H

#include "A_def.h"
#include "B_def.h"

inline A::A(int val) :_val(val)
{
}

inline void A::SetB(B *b)
{
    _b = b;
    _b->Print();
}

inline void A::Print()
{
    cout<<"Type:A val="<<_val<<endl;
}

#endif

// B.h
#ifndef B_H
#define B_H

#include "A_def.h"
#include "B_def.h"

inline B::B(double val) :_val(val)
{
}

inline void B::SetA(A *a)
{
    _a = a;
    _a->Print();
}

inline void B::Print()
{
    cout<<"Type:B val="<<_val<<endl;
}

#endif

Обратите внимание, что A_def .h и B_def.h являются «частными» заголовками, пользователи A и B не должны их использовать. Общий заголовок - A.h и B.h.

22
задан BoltClock 14 September 2012 в 11:31
поделиться

4 ответа

Вам нужно выполнить длительную операцию в фоновом потоке.

Существует несколько способов сделать это.

  1. Вы можете поставить очередь вызова метода для выполнения на поток потока потока (см. здесь здесь ):
    ThreadPool.QueueUserWorkItem(new WaitCallback(YourMethod));
    
    В .NET 4.0 вы можете использовать TaskFactory :
    Task.Factory.StartNew(() => YourMethod());
    
    И в .NET 4.5 и более поздних версиях вы можете ( и вместо TaskFactory.StartNew() следует использовать Task.Run():
    Task.Run(() => YourMethod());
    
  2. Вы можете использовать BackgroundWorker для большего контроля над этим методом, если вам нужны такие вещи, как обновления хода или уведомление, когда оно будет завершено. Перетащите элемент BackgroundWorker в форму и присоедините свой метод к событию dowork. Затем просто запустите работника, когда вы хотите запустить свой метод. Вы можете, конечно, создать BackgroundWorker вручную из кода, просто помните, что ему нужно избавиться от того, когда вы закончите.
  3. Создайте совершенно новый поток для вашей работы. Это самое сложное и не нужно, если только вам не нужен действительно тонкий контроль над потоком. См. Страницу MSDN в классе Thread , если вы хотите узнать об этом.

Помните, что с чем-либо, связанным с потоком, вы не можете обновить GUI или изменить какой-либо графический интерфейс элементы управления из фоновой нити. Если вы хотите что-либо сделать в графическом интерфейсе, вы должны использовать Invoke (и InvokeRequired), чтобы вызвать метод обратно в потоке графического интерфейса. См. здесь .

47
ответ дан Peter Duniho 1 September 2018 в 10:41
поделиться

Ничего не требуется. Используйте Application.DoEvents(); //repaint or respond to msg Например:

foreach (DirectoryInfo subDir in dirInfo.EnumerateDirectories())
{
    count = count + 1;
    listBoxControl4.Items.Add(count.ToString() + ":" + subDir.FullName);
    Application.DoEvents(); //allow repaint to see status
    ProduceListing(subDir, " ");
}

Это будет проходить через все папки рекурсивно и записать имена в список. Это может занять много времени. С помощью DoEvents () он будет показывать прогресс в каждом цикле. В принципе, вызов позволяет окнам в этом потоке обновлять что-либо в цикле windows msg. Обязательно наблюдайте за непреднамеренной рекурсией, как любой элемент управления в форме, который нужно нажать, даже если ваш первый не завершился. Это хорошо работает. (Это копия старого вызова Delphi Application.ProcessMessages (). Вы можете найти это, чтобы понять, почему он работает и что нужно отслеживать.

1
ответ дан Cody Gray 1 September 2018 в 10:41
поделиться

Очевидно, вам нужно использовать фоновые потоки. Я предлагаю вам прочитать эту бесплатную электронную книгу .

0
ответ дан Simon P Stevens 1 September 2018 в 10:41
поделиться
    private voidForm_Load(object sender, EventArgs e)
    {
        MethodInvoker mk = delegate
        {
            //your job
        };
        mk.BeginInvoke(callbackfunction, null);
    }

    private void callbackfunction(IAsyncResult res)
    {
        // it will be called when your job finishes.
    }

use MethodInvoker - самый простой способ.

5
ответ дан VOX 1 September 2018 в 10:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: