У меня есть кнопка в рамке браузера (CEFSharp).Если я нажимаю кнопку, я могу обработать косвенный щелчок с помощью моего метода C # DoSomething()
.DoSomething()
не вызывается в "Main-Thread".DoSomething()
должен вызывать _api.CallAnExportedComFunction()
в «Main-Thread» (некоторые функции в AutoCAD)._api.CallAnExportedComFunction()
является экспортированной функцией COM.Для вызова _api.CallAnExportedComFunction()
в «Главной теме» я использую BeginInvoke()
._api.CallAnExportedComFunction()
не следует вызывать параллельно.
Если я нажимаю кнопку один раз, все работает правильно.Если я нажимаю кнопку несколько раз очень медленно, все работает правильно.
Если я нажимаю кнопку очень быстро подряд, вызывается _api.CallAnExportedComFunction()
параллельно, но это не должно.Я пытался использовать lock()
внутри BeginInvoke, но он не работает.
Так почему же _api.CallAnExportedComFunction()
вызывается параллельно и как я могу избежать этого?Почему действие в условиях гонки BeginInvoke ()?Работает ли lock()
только между двумя РАЗНЫМИ потоками?
Я использую целое число ix, чтобы считать вверх и вниз.Оно никогда не должно достигать значения 2. Но это так.Если я заменю COM-вызов _api.CallAnExportedComFunction()
запросом http или режимом сна, мне кажется, что у меня нет условий гонки.
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
К сожалению, я не являюсьCOM-эксперт, и COM-код не мой, но если это важно, я могу попробовать добавить код.