Недопустимая операция в нескольких потоках. - C#

Узнай цену своей работы

Формулировка задачи:

Доброго времени суток. Так как в C# я новичек, мне пнадобилась Ваша помощь. Нашел пример в книге (мониторинг каталогов). Все устраивает, только мне нужно, чтобы сообщения выводились в ListBox, а не как MessageBox.
private void Form1_Load(object sender, EventArgs e)
        {
            // Создадим объект FileSystemWatcher и установим его свойства
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = @"C:\";
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
               | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            watcher.Filter = "*.txt";
            watcher.Changed += new FileSystemEventHandler(OnChanged);
            watcher.Deleted += new FileSystemEventHandler(OnChanged);
            watcher.Renamed += new RenamedEventHandler(OnRenamed);*/
            watcher.EnableRaisingEvents = true;
        }
           // События
           public void OnChanged(object source, FileSystemEventArgs e)
           {
               listBox1.Items.Add("Файл: " + e.FullPath + " " + e.ChangeType); 
               //MessageBox.Show("Файл: " +  e.FullPath + " " + e.ChangeType);
           }
Сначало покозалось, что задача простая, только вот вылетает такая ошибка: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "listBox1" не из того потока, в котором он был создан. Смотрел похожие темы - мало, в чем разобрался. Надеюсь на вашу помощь. Заранее спасибо!

Решение задачи: «Недопустимая операция в нескольких потоках.»

textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Threading;
using System.Drawing;
 
namespace ppp2
{
    public class Program:Form 
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new Program());
        }
        const int n = 4;
        public delegate void ParameterizedThreadStart(object obj);
        public ListBox lb = new ListBox();
 
        delegate void SetTextCallback(string text);
        private Thread demoThread = null;
        private System.ComponentModel.IContainer components = null;
 
        public class INFO
        {
            public int num = 0;
            public IntPtr ptr;
            public INFO(int num, IntPtr ptr)
            {
                this.num = num;
                this.ptr = ptr;
            }
        }
        Program()
        {
            lb.Parent = this;
            lb.Bounds = new Rectangle(0,0,100,100);
            INFO[] inf = new INFO[4];
            IntPtr ptr = lb.Handle;
            Thread[] t = new Thread[n];
            for (int i = 0; i < n; i++)
            {
                inf[i] = new INFO(i,ptr);
                t[i] = new Thread(new ThreadStart(this.ThreadProcSafe));
            }
            setTextSafeBtn_Click();
        }
        static void Go(object inf) 
        {
            INFO info = (INFO)inf;
            int i=info.num;
            IntPtr ptr = info.ptr;
            ListBox l = new ListBox();
        }
 
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
 
        private void setTextSafeBtn_Click()
        {
            this.demoThread = new Thread(new ThreadStart(this.ThreadProcSafe));
 
            this.demoThread.Start();
        }
 
        private void ThreadProcSafe()
        {
            this.SetText("This text was set safely.");
        }
 
        private void SetText(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.lb.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.lb.Items.Add("blablabla");
                this.lb.Items.Add("blablabla2");
            }
        }
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 3.875 из 5
Похожие ответы