Reputation: 2904
I have a button in a browser frame (CEFSharp). If I click the button I can handle the click indirect with my C# method DoSomething()
. DoSomething()
is not called in the "Main-Thread". DoSomething()
should call _api.CallAnExportedComFunction()
in the "Main-Thread" (some functions in AutoCAD). _api.CallAnExportedComFunction()
is an exported COM function. To call _api.CallAnExportedComFunction()
in the "Main-Thread" I am using BeginInvoke()
. _api.CallAnExportedComFunction()
should not be called in parallel.
If I press the button one time everything works correct. If I press the button some times very slow everything works correct.
If I press the button very rapidly in a row _api.CallAnExportedComFunction()
is called in parallel but it should not. I tried to use lock()
inside of BeginInvoke but it does not work.
So Why is _api.CallAnExportedComFunction()
called in parallel and how can I avoid it? Why have the Action's in BeginInvoke() race conditions? Does lock()
only works between two DIFFERENT threads?
I am using the integer ix to count up and down. It should never reach the value 2. But it does. If I replace the COM-call _api.CallAnExportedComFunction()
with an http request or a sleep it seems that I have no race-conditions.
private object _lock = new object();
private int ix = 0;
private void DoSomething()
{
System.Diagnostics.Debug.WriteLine($"ThreadAny: {System.Threading.Thread.CurrentThread.ManagedThreadId}");
// When initializing the Plugin _uiDispatcher.Dispatcher is set to System.Windows.Threading.Dispatcher.CurrentDispatcher
_uiDispatcher.Dispatcher.BeginInvoke(new Action(() =>
{
lock (_lock)
{
++ix;
System.Diagnostics.Debug.WriteLine($"+ThreadMainBeginInvoke: {System.Threading.Thread.CurrentThread.ManagedThreadId} => ix={ix}");
_api.CallAnExportedComFunction();
//System.Threading.Thread.Sleep(1000);
//var client = new System.Net.WebClient();
//var b = client.DownloadData("http://www.google.de");
--ix;
System.Diagnostics.Debug.WriteLine($"-ThreadMainBeginInvoke: {System.Threading.Thread.CurrentThread.ManagedThreadId} => ix={ix}");
}
}), null);
}
OUTPUT:
ThreadAny: 19
+ThreadMainBeginInvoke: 1 => ix = 1
-ThreadMainBeginInvoke: 1 => ix = 0
ThreadAny: 9
+ThreadMainBeginInvoke: 1 => ix = 1
ThreadAny: 27
+ThreadMainBeginInvoke: 1 => ix = 2
-ThreadMainBeginInvoke: 1 => ix = 1
Unfortunatly I am not a COM expert and the COM code is not mine but If it is important I can try to add some code.
Upvotes: 0
Views: 140