Непоследовательное поведение при вызове одного и того же метода из разных обработчиков событий
Я построил небольшой демон захвата камеры, который захватывает последовательность изображений с подключенной цифровой зеркальной фотокамеры с помощью EDSDK от Canon и оболочки C# Уэйна Хартмана.
Захват работает отлично и очень надежно, когда я звоню takePhotograph()
из тестовой кнопки нажмите обработчик на самой форме. Тем не менее, когда я пытаюсь позвонить takePhotograph()
от socketServer_MessageReceived()
, это очень ненадежно и часто приводит к тому, что приложение перестает отвечать на запросы. После отслеживания стека вызовов создается впечатление, что весь порядок вызовов перепутан, что в конечном итоге приводит к зависанию EDSDK при вызове. EdsDownload()
преждевременно (до того, как все изображения были захвачены).
Я из не многопоточной среды (Flex/ActionScript), и у меня есть догадка, я просто делаю что-то элементарно неправильное, связанное с моими обработчиками.
Вот суть моего кода:
private SocketServer socketServer;
private void initSocketServer()
{
socketServer = new SocketServer();
socketServer.Start( Convert.ToInt16( serverPortField.Text ) );
socketServer.MessageReceived += new EventHandler<SocketEventArgs>( socketServer_MessageReceived );
}
private void socketServer_MessageReceived ( object sender , SocketEventArgs e )
{
Console.WriteLine( "[CaptureDaemon] socketServer_MessageReceived() >> " + (String)e.Data );
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters( new[] { new DynamicJsonConverter() } );
dynamic obj = serializer.Deserialize( (String)e.Data , typeof( object ) );
if ( (String)obj.destinationID != "captureDaemon" )
return;
switch ( (String)obj.messageID )
{
case "capture":
takePhotograph( obj.body.successiveShotDelay , obj.body.successiveShots );
break;
}
}
private void testCaptureButton_Click ( object sender , EventArgs e )
{
takePhotograph( 500 , 4 ) );
}
1 ответ
Вы пытались обернуть takePhotograph
с Form.Invoke
(this.Invoke
)? Существует вероятность того, что, если он работает из графического интерфейса, он также будет работать, когда вы заставите правильный поток для вызова.