C#如何从工作线程调用主线程创建的对象上的方法?

C#如何从工作线程调用主线程创建的对象上的方法?,c#,asynchronous,multithreading,C#,Asynchronous,Multithreading,可能重复: 我是C#的初学者,最近我遇到了一个跨线程的ex。现在我到处寻找我的问题的答案,但似乎没有一个答案和我的一样,所以希望有人能帮上忙。这是我的问题解释 1) 我扩展了Microsoft.VisualBasic.PowerPacks.OvalShape,为其添加了更多功能,以满足我的需要,下面是我对该类的扩展: public class MyShape: Microsoft.VisualBasic.PowerPacks.OvalShape { int imageNumber;

可能重复:

我是C#的初学者,最近我遇到了一个跨线程的ex。现在我到处寻找我的问题的答案,但似乎没有一个答案和我的一样,所以希望有人能帮上忙。这是我的问题解释

1) 我扩展了Microsoft.VisualBasic.PowerPacks.OvalShape,为其添加了更多功能,以满足我的需要,下面是我对该类的扩展:

public class MyShape: Microsoft.VisualBasic.PowerPacks.OvalShape
{
    int imageNumber;

    public MyShape()
    {
        imageNumber = 0;
        this.BackgroundImage = global::_4InARow.Properties.Resources.grey;
    }

    public int getImageNumber()
    {
        return imageNumber;
    }

    public bool setImage(int imgNo)
    {
        imageNumber = imgNo;
        if (imgNo == 0) { this.BackgroundImage = global::_4InARow.Properties.Resources.grey; return true; }
        else if (imgNo == 1) { this.BackgroundImage = global::_4InARow.Properties.Resources.blue; return true; }
        else if (imgNo == 2) { this.BackgroundImage = global::_4InARow.Properties.Resources.red; return true; }
        else { return false; }
    }
}
2) 在designer类中,我为
类MyShape
创建了几个对象,然后使用
主线程或
UI线程将它们添加到ShapeContainer中。(突出显示ShapeContainer)

3) 在名为
(FourInARow\u Server)
的主类中,我使用
arrayLoad()
方法添加在锯齿数组中创建的所有对象。(类别如下所列)

当我使用工作线程(而不是创建对象的线程)异步访问方法
changeColor(int x,int y,int color)
时,会发生异常。 但是,如果我说

 if(circles[1][1].getImageNumber() == 0)  
  {//do something};  
(使用辅助线程和主线程的情况下工作正常)

关于异常的另一件事是,当抱怨工作线程调用在主线程中创建的对象时,引发异常的是ShapeContainer对象,而不是MyShape对象

我现在正在寻找一种解决方案,以安全地访问changeColor方法,使用两个线程更改每个对象的颜色。
就像我说的,我确实在网上寻找答案,但没有一个答案像我所面临的那样,我希望有人能帮助我。谢谢

public partial class FourInARow_Server : Form   
{  
    private MyShape[][] circles = new MyShape[7][];  
    private Socket newConnection;  
    private Thread newThread;  
    private int player;  
    private bool flag_MyTurn;  
    private bool flag_ConnectionAlive;  
    private bool flag_MoveAllowed;  
    private bool flag_EventBlocker; 

    public FourInARow_Server()
    {
        InitializeComponent();
        arrayLoad();
        player = 1;
        flag_MyTurn = true;
        flag_ConnectionAlive = false;
        flag_MoveAllowed = false;//variable needed to prevent user from loosing its turn if it clicks on a colomn that hasn,t got any more  available moves.
        flag_EventBlocker = true;
        this.labelSystemMessage.Text = "To begin play, please press \"Launch Server\" \n and wait for opponent to connect ";
    }

    private void arrayLoad()//Load all ovall shapes into an array
    {
        MyShape[] colOne = { x1y1, x1y2, x1y3, x1y4, x1y5, x1y6};
        MyShape[] colTwo = { x2y1, x2y2, x2y3, x2y4, x2y5, x2y6};
        MyShape[] colThree = { x3y1, x3y2, x3y3, x3y4, x3y5, x3y6};
        MyShape[] colFour = { x4y1, x4y2, x4y3, x4y4, x4y5, x4y6 };
        MyShape[] colFive = { x5y1, x5y2, x5y3, x5y4, x5y5, x5y6 };
        MyShape[] colSix = { x6y1, x6y2, x6y3, x6y4, x6y5, x6y6};
        MyShape[] colSeven = {x7y1, x7y2, x7y3, x7y4, x7y5, x7y6 };
        circles[0] = colOne; circles[1] = colTwo; circles[2] = colThree; circles[3] = colFour; circles[4] = colFive; circles[5] = colSix; circles[6] = colSeven;

    }

    private void changeColor(int x, int y, int color)
    {
        if (color == 0) { circles[x][y].setImage(0); }
        else if (color == 1) { circles[x][y].setImage(1); }
        else if (color == 2) { circles[x][y].setImage(2); }

        Application.DoEvents();
    }
}

在辅助线程中使用以下命令:

this.Invoke((MethodInvoker) delegate {
    changeColor(x, y, color);
});

在辅助线程中使用以下命令:

this.Invoke((MethodInvoker) delegate {
    changeColor(x, y, color);
});

这已经被问了很多次了。请参阅本页右侧的“相关”栏。这一问题已被多次询问和回答。请参阅本页右侧的“相关”栏。非常感谢Otiel它帮助我解决了问题。非常感谢Otiel它帮助我解决了问题。