0

我正在设计一个媒体播放器,我有一个名为 AddDirectory 的方法,它将指定目录中的所有电影添加到媒体播放器的数据库中。这个方法需要一段时间来处理,所以我决定让它在后台运行,这样用户就可以继续使用这个程序。

这是 AddDirectory 方法:

    /// <summary>
    /// Adds all the movies in the specified directory and all its subdirectories to the database.
    /// </summary>
    /// <param name="path">A string representing the directory path.</param>
    /// <returns>True if all the files were added successfully, false otherwise.</returns>
    /// <exception cref="System.ArgumentException">Thrown if the path does not lead to a directory.</exception>
    public static bool AddDirectory(string path)
    {
        if (!FileProcessing.IsDirectory(path))
        {
            return false;
        }

        List<string> filePaths = FileProcessing.GetDirectoryMovieFiles(path); //a list containing the paths of all the movie files in the directory

        //add the movie in a separate thread so as to not interrupt the flow of the program
        Thread thread = new Thread(() =>
        {
            foreach (string filePath in filePaths)
            {
                AddMovie(filePath);
            }
        });

        //make the thread STA and start it
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();

        return true;
    }

在同一个班级中,我有以下事件和委托:

    public delegate void MovieAddedHandler(MovieEventArgs e);

    /// <summary>
    /// Called on when a movie is inserted into the database.
    /// </summary>
    public static event MovieAddedHandler MovieAdded;

我需要这个事件,以便 GUI 知道何时将新电影添加到数据库中,因此它可以更新 GUI 并相应地通知用户。因此,当我添加一个包含 50 部电影的目录时,该事件会被调用 50 次。

现在 GUI 更新是我遇到困难的地方。

我有以下代码段,它是每当用户单击 GUI 中的“添加目录”标签时调用的方法的一部分。

MovieInsertion.MovieAdded += (e2) =>
{
    this.movies = MovieDataRetrieval.GetMovies();
    this.labels.Clear();
    this.InitializeMovieLabels();
};

GetMovies() 方法返回数据库中所有电影的列表(由单独的 Movie 类表示)。然后我清空GUI网格中的所有标签,然后再次初始化,这样每次添加电影时,用户可以立即在程序中访问该电影,而无需等待目录中的其余电影被添加。

错误本身在 InitializeMovieLabels() 方法中被调用:

foreach (Label labelIterator in labels)
{
    this.grid.Children.Add(labelIterator);
}

“标签”变量是代表数据库中电影的所有标签的列表。我想将每个标签添加到网格中。

我得到的错误是(如标题中所述):“调用线程无法访问此对象,因为不同的线程拥有它。”

我对线程有点(非常)缺乏经验,我尝试寻找解决方案但没有成功。对不起,如果我对细节有点过分了:)。

任何帮助,将不胜感激。

4

1 回答 1

0

使用MethodInvoker从不同线程更新 GUI 的地方。

您的 labels.clear() 语句尝试从不同的线程更新 GUI。所以使用这种类型的代码。

if(this.labels.InvokeReqiured)
{
    this.labels.Invoke( (MethodInvoker) ( ()=> this.labels.Clear() ) );
}
else
this.labels.Clear();

如果您想从不同的线程更新 GUI,请确保使用MethodInvoker委托。

于 2012-06-07T15:13:14.637 回答