C# Invoke 멈춤 현상

안녕하세요. 현재 저는 C# .net을 이용하여 프로그램을 제작 중입니다.
다름이 아니라 Invoke를 사용하다가 멈춤 현상이 일어나 어떤 원인인 지 궁금해서 글을 씁니다.
먼저 문제가 되는 구조에 대해 설명 드리겠습니다.
카메라를 인식하는 Thread에서 카메라 라이브 객체를 제작 후 UI Control에 추가하는 구조입니다.
여기서 UI Control에 추가하는 부분이 UI Thread가 아닌 카메라 인식하는 Thread에서 추가하기 호출 되기 때문에 아래와 같이 코드를 작성하였습니다.
하지만 Invoke 줄이 실행 된 후 AddCameraView 함수가 호출 되지 않네요.
혹시 호출 되지 않는 이유를 아시는 분 꼭 댓글 부탁드립니다.

public void OnCameraAddEvent(object sender, CameraAddArgs e)
{
    Console.WriteLine("현재 Thread : {0}", Thread.CurrentThread.ManagedThreadId);

    if (this.camScrollView.InvokeRequired)
        this.camScrollView.Invoke(new Action(delegate () { AddCameraView(e.cameraView, e.cameraName); }));
    else 
        AddCameraView(e.cameraView, e.cameraName);
}
1개의 좋아요

재현되는 프로젝트를 같이 첨부해 주시겠어요?

1개의 좋아요

회사 프로젝트라 코드 자체를 첨부하는 것은 불가능하지만 내용으로 설명드리겠습니다.

private void AddCameraView(CaptureCameraView view)
{
    Console.WriteLine("D");
    this.cameraViews.Add(view);
    this.camScrollView.Controls.Add(view);
    CameraController.Instance.setTriggerMode(view.Index, false);
    CameraController.Instance.Grab(view.Index);
}

이해가 안되는 부분이 있으시면 바로바로 답 드리겠습니다.!

1개의 좋아요

UI Thread를 꽉잡고 있는 부분이 있어서 Invoke를 했을 때 먹통이 되는게 아닌가 싶네요.

1개의 좋아요

혹시 꽉 잡는다는 예시 알 수 있을 까요…? 아직 무슨 의미인 지 모르겠네요.

1개의 좋아요

재현 프로젝트라 하심은 문제가 발생하는 부분에 대해서 딱 샘플 프로젝트를 만들어서 올려달라고 하신 의미이실겁니다.

유닛테스트 기반으로 프로젝트를 구성했다면 딱 모듈과 유닛테스트만 떼서 올릴 수 있겠지만 많은 회사들이 그렇지 못할거구요.

그래서 프로젝트에서 문제가 동일한 문제가 발생하는지 다른 거 다 제외한 문제가 발생하는 정도의 샘플 프로젝트를 스스로 만들어 보는 겁니다.

재현 프로젝트에서 문제가 발생하지 않았다면, 다른 것이 원인이다 라는 것을 스스로 파악할 수 있고, 아니면 내가 샘플 프로젝트를 잘못 만든 것일 수도 있습니다.

다만 그것은 코드로 보여져야 알 수 있죠.

질문자 님께서 정성들여서 샘플프로젝트와 질문을 디테일하게 하실 수록 코드를 보고 답변자가 빠르게 처리합니다.

그렇기 때문에 DevExpress 같은회사에서도 코드에 관한 질문을 올릴 때는 샘플프로젝트를 첨부하라고 권장하는 것입니다.

처음이라 너무 어렵고, 귀찮을 수 있지만 본인의 시간을 최대로 투자해서 답변해주시는 분의 시간을 최소화 하고 핑퐁타임으로 오는 레이턴시를 줄일 수 있는 가장 좋은 수단은 샘플 코드입니다.

그렇게 샘플 프로젝트를 만드는 습관은 문제에 대해 구체화 하는 훈련도 되는거라서 한번 만들어보시는 것을 추천드립니다.

3개의 좋아요

아마도 OnCameraAddEvent 메소드명으로 미루어 봐서
샘플소스를 올리셔도 camera가 없으면 힘드실것같네요
(web cam 이라면 저런문제가 생기지도 않겠지요)

Dispacher 관련으로 다양한 검색을 통해서 이것저것 적용해보시거나
근데
Dispatcher.Invoke(DispatcherPriority.Normal
, new Action(
delegate
{
//사용할 메서드 및 동작
MainUi.Children.Add(newIoUC);
}));

Current handler 잡아와서 Priority 설정하지 않나요??
소스만 봐서 잘모르겠지만 scroll 구문도 보이고
ui thread가 답이 없는경우가 많아서 판단하기 힘듭니다.

1개의 좋아요

답변 감사합니다.
현재 DalsaCamera를 사용하여 Camera 자체는 Dalsa Library 관련된 코드입니다.
camScrollView Control은 FlowLayoutPanel입니다.
간단하게 아래에 구조를 적어보았습니다.

카메라 인식 Thread
인식 → 카메라 객체 생성 → Control 추가

인식 : 카메라 연결 및 해제 인식
카메라 객체 생성 : 카메라 View Control 생성 및 카메라 정보
Control 추가 : FlowLayoutPanel에 카메라 View Control 추가

카메라 View Control

public class CameraView: PictureBox
{
    private SapView sapView;

    public CameraView() { }
    protected override void OnPaint(PaintEventArgs e)
    {
        if (sapView != null && sapView.Initialized)
        {
            sapView.OnPaint();
        }
        base.OnPaint(e);
    }

    public SapView View
    {
        get { return this.sapView; }
        set
        {
            this.sapView = value;

            if (this.sapView != null)
            {
                this.sapView.Window = this;
            }
        }
    }

     public void UpdateViewSize(Size size)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<Size>(UpdateViewSize), size);
            }
            else
            {
                Initialized = true;
                this.Size = size;
                decimal WidthScalor = (decimal)(100.0f * this.Width / this.sapView.Buffer.Width);
                decimal HeightScalor = (decimal)(100.0f * this.Height / this.sapView.Buffer.Height);
                this.sapView.SetScalingMode((float)WidthScalor / 100.0f, (float)HeightScalor / 100.0f);
            }
        }
}
1개의 좋아요

위 답변 코드 UpdateViewSize 함수에서 멈춤 현상이 일어나네요.

this.Invoke(new Action<Size>(UpdateViewSize), size);

이 줄에서 멈춤 현상이 일어납니다. 활어회소주원샷우럭두개더 개발자님 의견을 통해 생각 해보았는데, 해당 PictureBox에 View가 계속 UI Thread를 잡아 먹고 있는 게 아닐 까? 생각이 드네요.

다른 분들 생각도 듣고 싶습니다.!

3개의 좋아요

사실 근본 원인을 찾는게 우선이긴한데요…ㅎㅎInvoke를 BeginInvoke로 바꿔보시겠어요?
Invoke는 내 차례와서 동작할때까지 존버!
BeginInvoke는 아 모르겠고 이따가 이거 할 수 있으면 해줘. 그럼 나는 이만 빠염!
하는것입니다 ㅎㅎ

3개의 좋아요

안녕하세요.

Image Grab Complete Event를 Subscribe 받아 UI에 올리다보면

Event를 실행하는 Thread와 UI Thread와 충돌이 발생합니다.

모든 Event에 해당하는게 아니라 Dalsa lib로 Grab을 하게되면 PC의 SDK를 호출하여 Grab하는 형태다보니 별개 Thread를 통해 Image를 받아오십니다.

이럴때는 Event를 Subscribe 할 때 Current Thread를 변수로 저장하셨다 Action을 태우셔야야합니다.

2개의 좋아요