Недопустимая операция в нескольких потоках. - C#
Формулировка задачи:
Доброго времени суток.
Так как в C# я новичек, мне пнадобилась Ваша помощь.
Нашел пример в книге (мониторинг каталогов). Все устраивает, только мне нужно, чтобы сообщения выводились в ListBox, а не как MessageBox.
Сначало покозалось, что задача простая, только вот вылетает такая ошибка: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "listBox1" не из того потока, в котором он был создан.
Смотрел похожие темы - мало, в чем разобрался.
Надеюсь на вашу помощь.
Заранее спасибо!
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);
}Решение задачи: «Недопустимая операция в нескольких потоках.»
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");
}
}
}
}