在FileSystemEventHandler之后更改剪贴板



这里是c#的新手,第一次处理事件处理程序。我正在编写的程序的一个步骤是,每次在某个位置创建文件时都要更改剪贴板。以下是我到目前为止的想法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace ConsoleApplication1
{
    class Program
    {
        [STAThread]
        public static void Main()
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = @"C:Input";
            watcher.Filter = "*.csv";
            watcher.Created += new FileSystemEventHandler(ProcessFile);
            watcher.EnableRaisingEvents = true;
            Console.ReadLine();
        }
        public static void ProcessFile(object source, FileSystemEventArgs e)
        {
            try
            {
                Clipboard.SetText("text");
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc);
                Console.ReadKey();
            }
        }
    }
}

抛出了一个异常,即当前线程不处于STA模式,需要在Main方法中进行标记,但我相信我做到了。如何更改此处的剪贴板?

问题是FileSystemWatcher将在单独的线程上触发事件。您需要做一些事情,以便剪贴板操作与Main方法在同一个线程中进行。

方法#1:使用Application.Run,即使您不使用WinForms。它在主线程上旋转一个循环,等待事件发生。类似这样的东西:

static Form InvokerForm;
public static void Main()
{
    InvokerForm = new Form();
    var dummy = InvokerForm.Handle; // form handle creation is lazy; force it to happen
    var watcher = new FileSystemWatcher();
    watcher.SynchronizingObject = InvokerForm;
    watcher.Path = @"C:Input";
    watcher.Filter = "*.csv";
    watcher.Created += new FileSystemEventHandler(ProcessFile);
    watcher.EnableRaisingEvents = true;
    Application.Run();
}

这告诉观察者在您创建的(不可见)表单上调用Invoke,并将处理程序作为参数传递。这基本上是将其排队等待稍后调用。与此同时,Application.Run位于主线程上,旋转一个循环,等待这样的事件发生。当它注意到这一点时,它继续并在正确的线程上调用ProcessFile

方法#2:如果这看起来太古怪,那是因为它有点古怪。"正确"的方法是使用自定义SynchronizingObject。不幸的是,似乎没有内置,但有一篇文章描述了如何创建实现ISynchronizeInvoke的委托队列。

这种方法的净效果是一样的:最终在主线程上有一些东西,等待调用被请求,然后执行它们。只有这一次,你才能对它的所有内部进行编码,同时使程序在系统资源使用方面更加精简。

相关内容

  • 没有找到相关文章

最新更新