Доступ к элементам формы Form1 из файловой системы - PullRequest
0 голосов
/ 07 февраля 2012

У меня есть программа, которая проверяет изменения в файле, затем, как только файл изменяется, он читает его и обновляет некоторые метки. «Однако происходит сбой, потому что я пытаюсь изменить элементы в потоке из другого потока» ~ Или мне так кажется. Есть идеи?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
using System.IO;
using System.Threading.Tasks;


namespace RoomAutomation
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void readfile_Click(object sender, EventArgs e)
        {

            string[] lines = System.IO.File.ReadAllLines(@"C:\Users\Dandrews\control.txt");
            FileSystemWatcher fsw = new FileSystemWatcher();
            fsw.Path = @"C:\Users\Dandrews\";
            fsw.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite |
                            NotifyFilters.DirectoryName | NotifyFilters.FileName;
            fsw.Changed += new FileSystemEventHandler(OnChanged); 
            fsw.EnableRaisingEvents = true;
            if (lines[0] == "1:lights")
            {
                Lights.Text = "Lights are on.";
            }
            if (lines[0] == "0:lights")
            {
                Lights.Text = "Lights are off.";
            }
            if (lines[1] == "1:camera")
            {
            Camera.Text = "Camera is on.";
            }
            if (lines[1] == "0:camera")
            {
                Camera.Text = "Camera is off.";
            }
            if (lines[2] == "1:speakers")
            {
                Speakers.Text = "Speakers are on.";
            }
            if (lines[2] == "0:speakers")
            {
                Speakers.Text = "Speakers are off.";
            }
            if (lines[3] == "1:playlist")
            {
                Playlist.Text = "Playlist is on.";
            }
            if (lines[3] == "0:playlist")
            {
                Playlist.Text = "Playlist is off.";
            }        
        }
        private void OnChanged(object source, FileSystemEventArgs e)
        {            
            Console.Write("Changes");
            //Lights.Text = "New label Text";

        }
    }
}

`

Ответы [ 2 ]

1 голос
/ 07 февраля 2012

Это потому, что FileSystemWatcher вызывает свои события в потоке потоков. Что является естественным способом, эти события файловой системы происходят асинхронно. Вы не можете напрямую получить доступ к любым компонентам пользовательского интерфейса в обработчике событий, они не являются поточно-ориентированными. InvalidOperationException существует, чтобы напомнить вам, что вы не можете.

Исправление требует добавления одной строки кода:

        fsw.SynchronizingObject = this;

Что заставляет FileSystemWatcher маршалировать вызов обработчика событий для потока, который создал форму, потока пользовательского интерфейса. Это не обязательно лучшее решение, поскольку маршалинг вызова требует много накладных расходов. Но с этим решением у вас все будет в порядке, поскольку у вас есть для маршалинга для каждого события в любом случае с кодом, который у вас есть сейчас.

0 голосов
/ 07 февраля 2012

.NET 2.0 и выше не позволяет вам получать доступ к элементам пользовательского интерфейса из других потоков .Вы должны вызвать вызов кода, который вы хотите запустить на элементе управления.Если вы портируете код .NET 1.1, вот простой способ сделать вашу жизнь проще:

http://codebetter.com/jeremymiller/2006/11/06/using-anonymous-methods-with-control-invoke/

...