从ISampleGrabber获取字符串并在第一个窗体中更新文本框

3

我希望能够通过另一个类更新我的UI界面。我已经尝试通过创建一个form1对象并使用方法来更新文本框来实现此操作。但是这会导致一个错误,告诉我我的设备未正确运行。

所以基本上我如何在我的samplegrabber.cs类中使用我的Form1更新文本框?这个类被不断地调用,但是我只需要使用字符串。

ISampleGrabber类调用SampleCB方法,该方法包括:

public int SampleCB(double sampletime, IMediaSample sample)
    {
        if (sample == null)
        {
            return -1;
        }
        try
        {
            int length = sample.GetActualDataLength();
            IntPtr buffer;          
            if (sample.GetPointer(out buffer) == 0 && length > 0)
            {
                Bitmap bitmapOfFrame = new Bitmap(width, height, stride, PixelFormat.Format24bppRgb, buffer);
            }                
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
        Marshal.ReleaseComObject(sample);
        return 0;
    }

在if语句中创建了form1对象,即使我创建该对象(甚至没有f1.updateTextBox(id);)也会出现错误。

`updateTextBox1'是在Form1中创建的:

    public void updateTextBox1(string id)
    {
        textBox1.Text = id;
    }

我收到的错误如下:
COMException(0x8007001F) - 系统附加的设备未正常工作。

1
你能分享一些代码示例展示你尝试过的吗?另外,你能发布精确的错误信息吗? - Krease
添加了相关代码。 - legohead
1个回答

2
SampleCB会在一个辅助线程上被调用。您不应该在此回调中执行任何与UI相关的操作,相反,您可能需要将值存储在成员变量中并指示需要在UI线程上继续,例如通过向自己发送消息,然后在正确的线程上处理它。


我尝试使用给出的示例,但似乎无法使其正常工作。在我的SampleCB中,目前正在显示消息框,我应该如何表达(缺乏更好的措辞)“我完成了,这是字符串”? - legohead
1
你有多种选择来实现它,但是因为你寻求的是简单的东西,让我提供给你的不是最好的,而是被认为最容易理解的。在你的回调函数中,你将字符串存储在内部变量中,并将另一个 bool 变量设置为 true。然后,在你的窗口/表单上,你有一个定时器,以固定时间间隔调用其事件回调函数,从那里当你看到这个 true 时,你也可以使用存储的字符串。 - Roman R.
从我的理解来看,您的意思是将计时器添加到我的UI线程/第一个表单中?我需要回调哪个事件?很抱歉我不太理解,因为我很新,对于同时使用多个线程以及它们如何共享数据还不是很熟悉。 - legohead
计时器的 Tick 事件在 UI 线程上调用。这是您的策略:在 SG 回调上尽量少做工作(只将值存储到安全位置),然后计时器的事件为您提供了在“正确”线程上接管的机会(这是一个简化版本:一旦您对此满意,您需要阅读有关同步以及如何使用例如 ReaderWriterLock 保护这些数据的内容)。 - Roman R.
所以,在我的UI线程上,我会启动一个计时器,并设置一个事件处理程序,每5秒钟触发一次等。然后在我的计时器事件中,我该如何检查sampleGrabber线程以检查此bool以查看是否可以访问字符串?我只能想到创建一个类对象并调用SampleCB,但这样做会创建一个错误,因为它已经被调用了,我告诉sampleGrabber使用哪个回调函数? - legohead
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接