[英]$exception {Invoke or BeginInvoke cannot be called on a control until the window handle has been created.} System.InvalidOperationException
[英]System.InvalidOperationException Invoke exception
我在調用方法中有這個異常,我不知道為什么。
System.InvalidOperationException: 'Operación no válida a través de subprocesos: Set tuvo acceso al control 'Form2' desde un subproceso distinto aquel en que lo creó。'
谷歌將其翻譯為:
System.InvalidOperationException:'通過線程進行的無效操作:'Form2'控件是從與創建它的線程不同的線程訪問的。
例如,如果我從按鈕調用調用它可以正常工作,但我需要從 FileSystemWatcher 調用它。
List<Thread> listThreads = new List<Thread>();
private void Form1_Load(object sender, EventArgs e)
{
RunFileSystemWatcher();
}
public void RunFileSystemWatcher()
{
FileSystemWatcher fsw = new FileSystemWatcher();
fsw.Path = "C:/Users/Gaming/Documents";
fsw.NotifyFilter = NotifyFilters.LastAccess;
fsw.NotifyFilter = NotifyFilters.LastWrite;
//fsw.NotifyFilter = NotifyFilters.Size;
//fsw.Created += FileSystemWatcher_Created;
fsw.Changed += FileSystemWatcher_Changed;
fsw.Filter = "*.txt";
fsw.EnableRaisingEvents = true;
}
Boolean abrir = true;
private void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
if (abrir) {
for (int i=0; i<5; i++)
{
Thread hilo = new Thread(() => showForms(new Form2()));
hilo.Start();
listThreads.Add(hilo);
abrir = false;
}
}
else{
for(int i=0; i<listThreads.Count; i++)
{
try
{
Invoke((MethodInvoker)delegate {
listForms[i].Close();
});
listThreads[i].Abort();
}
catch (ThreadAbortException)
{
}
}
}
}
List<Form2> listForms = new List<Form2>();
private void showForms(Form2 form)
{
listForms.Add(form);
form.ShowDialog();
}
您與主線程 UI 發生了同步沖突。
您必須將調用與主線程同步到 UI 控件上的任何操作。
您可以使用 BackgroundWorker。
或這個:
static public class SyncUIHelper
{
static public Thread MainThread { get; private set; }
// Must be called from the Program.Main or the Main Form constructor for example
static public void Initialize()
{
MainThread = Thread.CurrentThread;
}
static public void SyncUI(this Control control, Action action, bool wait = true)
{
if ( !Thread.CurrentThread.IsAlive ) throw new ThreadStateException();
Exception exception = null;
Semaphore semaphore = null;
Action processAction = () =>
{
try { action(); }
catch ( Exception except ) { exception = except; }
};
Action processActionWait = () =>
{
processAction();
if ( semaphore != null ) semaphore.Release();
};
if ( control != null
&& control.InvokeRequired
&& Thread.CurrentThread != MainThread )
{
if ( wait ) semaphore = new Semaphore(0, 1);
control.BeginInvoke(wait ? processActionWait : processAction);
if ( semaphore != null ) semaphore.WaitOne();
}
else
processAction();
if ( exception != null ) throw exception;
}
}
用法:
this.SyncUI(listForms[i].Close /*, true or false to wait or not */);
和:
this.SyncUI(() => form.ShowDialog() /*, true or false to wait or not */);
和:
private void Form1_Load(object sender, EventArgs e)
{
SyncUIHelper.Initialize();
RunFileSystemWatcher();
}
您需要更正 FileSystemWatcher_Changed 中的代碼,因為它有問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.