Reputation: 1
I'm writing a macro program, and have almost everything set up expect mouse control. The problem it that the logic is running separate from the UI thread, and that I don't know how to convert the mouse from the UI thread to the new one. This is the error I get without any invoking.
System.InvalidOperationException: 'Cross-thread operation not valid: Control 'Form1' accessed from a thread other than the thread it was created on.
I tired to remedy this by invoking the Cursor, but it is not invokable it seems. Is there any way to disable thread safety and would that even be a good idea?
if (Cursor.Current.Handle.InvokeRequired) //and other variations of it
this.Invoke(new MethodInvoker(() => this.Cursor = new cursor(Cursor.Current.Handle)));
else this.Cursor = new cursor(Cursor.Current.Handle);
Give the error
'IntPtr' does not contain a definition for 'InvokeRequired' and no accessible extension method 'InvokeRequired' accepting a first argument of type 'IntPtr' could be found (are you missing a using directive or an assembly reference?)
Upvotes: 0
Views: 1424
Reputation: 3569
The context belongs to the Form
, not the cursor. That means you need to test for invocation on the form instance. But there is an other option though: grab the synchronization context itself.
var f = new Form();
var ctx = WindowsFormsSynchronizationContext.Current;
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Action a = () =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
f.Cursor = new Cursor(Cursor.Current.Handle);
};
Task.Run(async () => {
await Task.Delay(TimeSpan.FromSeconds(5));
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
ctx.Post(_ => a(), null);
});
Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(10));
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
if (f.InvokeRequired) f.Invoke(a); else a();
});
f.ShowDialog();
Upvotes: 1