Проблема с делегатами в C #, формы и несколько решений - PullRequest
3 голосов
/ 19 февраля 2010

РЕДАКТИРОВАТЬ: это приложение winform, извините за неудобства

Отказ от ответственности: это задание мы получили в колледже, и я застрял в этом конкретном разделе кода.У меня есть 2 решения в Visual Studio 2008, одно для формы и одно для DLL, которые форма может использовать для функциональности.Идея состоит в том, чтобы отправлять HTML-письма от клиента и использовать делегат для подтверждения этого.

Один класс DLL содержит только одного делегата:

namespace Console.Grand
{
    public delegate void ObserverDelegate(string info);
}

файл с именем Delegate.cs

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

private void Update(string info)
{
   this.logBox.Text += Environment.NewLine + info;
}

Переменная logBox представляет собой TextArea в форме.

При передаче происходит следующее (BL означает «Бизнес-уровень»):

BL_MailOut bm = new BL_MailOut(s1,ListViewAdresses());
ObserverDelegate deleg = new ObserverDelegate(Update);
bm.SendMail(deleg);

Конструктор BL_MailOut выглядит следующим образом (мы сейчас в DLL):

public BL_MailOut(StandardPage page, List<MailAddress> list)
{
    this.s = page;
    this.adresslist = new List<MailAddress>();
    foreach (MailAddress m in list)
    {
        this.adresslist.Add(m);
    }
}

И метод SendMail:

public void SendMail(ObserverDelegate deleg)
{
    IO_MailOut im = new IO_MailOut(s, adresslist, deleg);
    Thread t = new Thread(new ThreadStart(im.Send));
    t.Start();
}

И, наконец, мы приходим к методу Send ():

public void Send()
{
    SmtpClient sc;
    MailMessage msg;
    string info;
    foreach (MailAddress adress in this.list)
    {
        try
        {
            sc = new SmtpClient(HOST);
            msg = new MailMessage(SENDER, adress.Address);
            msg.IsBodyHtml = true;
            msg.Subject = "test";
            msg.Body = page.ToString();
            sc.Send(msg);
            info = "(" + DateTime.Now + ") MAIL SENT TO" + Environment.NewLine + adress.Address;
            deleg(info);
        }
    }

Я ловлю необходимые ошибки, я просто их опущуздесь, чтобы сэкономить место.

Когда достигается deleg(info);, ожидаемое поведение будет таким, что textBox получит необходимый текст.Однако это не так.Экземпляр делегата сохраняется, и компилятор не выдает ошибку.Я прочитал материал на сайте MSDN о делегатах, но там ничего не помогло.

Ответы [ 2 ]

1 голос
/ 19 февраля 2010

Ваш метод Update в форме выполняет операцию с несколькими потоками, что недопустимо.

Измените метод обновления в форме на этот

    private void Update(string info)
    {
     ObserverDelegate callBack =  new ObserverDelegate((x) =>
            {
                this.logBox.Text += Environment.NewLine + info;
            });             

        if (this.InvokeRequired)
            this.Invoke(callBack, info);
        else
          callBack(info);
    }
1 голос
/ 19 февраля 2010

Я делаю нечто подобное в моей программе ... вот как я это сделал.

    public void setBoxText(string value)
    {
        if (InvokeRequired)
            Invoke(new SetTextDelegate(setBoxText), value);
        else
            statusBox.Text += value;
    }

    delegate void SetTextDelegate(string value); 

Затем я вызываю setBoxText всякий раз, когда хочу добавить текст в поле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...