尝试访问静态方法时的跨线程问题

时间:2019-06-05 12:59:19

标签: c# multithreading

所以我对线程没有很多深入的了解。我知道一些基本的事情,例如在线程上启动计时器或在需要在其他线程中使用它时调用文本框。我在此当前应用程序中使用了线程,以便我正在执行的过程在后台运行,并且运行良好。

解决问题

我已经禁用了表格边框,对于那些这样做的人来说,这知道不再有表格可拖动性(出于美观目的,我这样做了)。我对方法进行编码不是问题,以便我可以再次移动它。看起来是这样:

 public static class UserMouseEvents
    {
        //is the mouse being pressed
        private static bool mouseDown;

        //where was the pointer last
        private static Point lastLocation;

        //on which form is it coming from
        private static Form originForm;

        public static Form OriginForm { get => originForm; set => originForm = value; }

        public static void UserMouseDown(MouseEventArgs e)
        {
            mouseDown = true;
            lastLocation = e.Location;
        }
        public static void UserMouseUp()
        {
            mouseDown = false;
        }
        public static void UserMouseMove(MouseEventArgs e)
        {
            if (mouseDown)
            {
                OriginForm.Location = new Point(
                (OriginForm.Location.X - lastLocation.X) + e.X, (OriginForm.Location.Y - lastLocation.Y) + e.Y);

                OriginForm.Update();
            }
        }
    }

它就像一种魅力。我将其设置为静态方法,以便轻松访问所有表单。现在我遇到一个问题,需要同时打开两个表单。

应该模拟一个呼叫。因此,在一种形式上,我有一个类似于手机的用户界面,并且它正在运行一个计时器(仅使用计时器类,没有什么花哨的)。在另一种形式上,我可以记录通话记录,也许可以查看有关谁在通话的详细信息。因此,为此仅使用ShowDialog()无效,我不得不在运行手机表单的地方创建一个新线程。这样可以确保我可以在表格之间自由切换。

我必须在第二个线程中调用UserMouseMethods。只是为了对每个元素进行一些进一步的解释,我希望可拖动性起作用,因为我需要在该元素事件上调用UserMouseDown,UserMouseMove和UserMouseUp。例如pnlHeading_MouseDown,pnlHeading_MouseMove,pnlHeading_MouseUp

现在,我使用与其他所有表格完全相同的方式进行操作,但出现此错误

System.InvalidOperationException:“跨线程操作无效:控制'CallForm'是从不是在其上创建线程的线程访问的。”

CallForm是手机表格

我一直坐在互联网上,试图弄清楚如何使两个线程同时访问该类,而我正式遇到了砖墙。

有人可以帮忙吗?

注意:我已经尝试过methodInvoker,但不确定是否正确执行了操作。这是我尝试解决此问题的一系列最新尝试。

编辑:我想我弄清楚了为什么我确实得到了错误。因此,为了使该方法知道应该在哪种形式上进行可拖动性,我需要将OriginForm解析为该形式。所以我说两种形式的OnLoad事件都要做

UserMouseEvents.OrginForm = this; 

因此,我假设发生的是CallForm将该资源置于锁中。因此,当我尝试再次在主窗体上访问它时。它告诉我,我正在尝试在另一个未创建调用线程的线程上访问CallForm。

这可能会提供一些见识。

1 个答案:

答案 0 :(得分:0)

好的,因此该问题的解决方案比我预期的简单得多。如果您查看我的编辑,我说的就是问题所在。基本上发生的是我设置了

UserMouseEvents.OriginForm = this;

在两个表单的表单加载中,这样做意味着它仅在该行上运行一次。因此,当我尝试在调用表单上移动时,它会覆盖OriginForm,然后当我想在主表单上再次移动时,它试图移动CallForm,但它在另一个线程上。

简单的解决方案: 移动此:

UserMouseEvents.OriginForm = this;

进入表单上的Activate事件。

很多人说我的方法不应该是静态的。但是,我现在将其保留为静态。我没有很多时间来解决这个问题。另外,如果您能就此答案为什么不应该是静态的发表评论,我将不胜感激。这从来都不是我经常在课堂上教我的东西,也不是我在上课,观看视频时学到的东西。