none
Вызов метода из фонового потока RRS feed

  • Вопрос

  • Помогите правильно совладать с потоками.

    есть класс, которые обрабатывает некий поток данных.
    т.к. данных очень много, то логично их было обработать в фоновом потоке.

    в этом классе так же есть event.
    public event EventHandler ChangeStatus;

    и во время обработки потока, требуется вызвать этот event приопределенных условиях.

    сейчас я это делаю так:
     if (ChangeStatus != null)
                {
                    ChangeStatus.Invoke(this, e);
                }
    но у меня появляется при выполнении обшибка, т.к. вызов происходит из фонового потока, и часто в методе который вызывается происходят разные изменения, например отображение статуса в окне.

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






    20 ноября 2014 г. 11:17

Все ответы

  • using System; using System.Windows.Forms; using System.Threading; namespace Main { public partial class MainForm : Form { public MainForm() { InitializeComponent(); Action actLog = new Action ( Log ); actLog.BeginInvoke ( null,null ); } private void btStart_Click ( object o, EventArgs e ) { Instance = this; MyClass = new myClass (); } static AutoResetEvent LogMessageIsReadyEvent = new AutoResetEvent ( false ); public myClass MyClass; public static MainForm Instance; public string Message; public void LogPut ( string logString )
    { Message = logString;
    LogMessageIsReadyEvent.Set();

    } public void Log () { while ( true ) { LogMessageIsReadyEvent.WaitOne(); LogMessageIsReadyEvent.Reset(); Invoke ( new MethodInvoker ( () => { rtbLog.AppendText ( Message+"\n" ); // RichTextBox rtbLog.ScrollToCaret(); })); } } } public class myClass { public myClass () { MainForm.Instance.LogPut ( "Hello world!" ); } } }








    • Изменено QazRdx 20 ноября 2014 г. 15:28
    20 ноября 2014 г. 15:19
  • Добрый день.

    Если у вас WinForms приложение, то вы можете сделать так:

     
    if (ChangeStatus != null)
    {
        var someForm = Application.OpenForms.Cast<Form>().First();
        if (someForm.InvokeRequired)
        {
            someForm.BeginInvoke((Action)(() => ChangeStatus.Invoke(this, e)));
        }
        else
        {
            ChangeStatus.Invoke(this, e);
        }
    }

    Единственно, вам нужно быть уверенным, что у приложения есть хотя-бы одна видимая форма...
    21 ноября 2014 г. 7:21
    Отвечающий