【问题标题】:Update a value from a delegate method on GUI thread without calling the event from the GUI从 GUI 线程上的委托方法更新值,而不从 GUI 调用事件
【发布时间】:2015-07-05 05:28:54
【问题描述】:

我是使用http://www.ctsfutures.com/wiki/T4%20API%2040.MainPage.ashx 的模板编写的示例 C# 程序

以下是部分代码:

声明来自其 API 的 moAccounts

internal AccountList moAccounts;

创建委托

private delegate void OnPositionUpdateDelegate(T4.API.Position poPosition);

它在 Init() 内部注册

moAccounts.PositionUpdate += new T4.API.AccountList.PositionUpdateEventHandler(moAccounts_PositionUpdate);

我相信当输入交易并更新头寸时会调用它。位置就像您拥有 100 股 Google 等。所以它只有 100 股。

 //' Event that is raised when positions for accounts have changed.
    private void moAccounts_PositionUpdate(AccountList.PositionUpdateList poPositions)
    {

        // Display the position details.

        {

            foreach (AccountList.PositionUpdateList.PositionUpdate oUpdate in poPositions)
            {
                // If the position is for the current account
                // then update the value.

                if (object.ReferenceEquals(oUpdate.Account, moAccount))
                {
                    // Invoke the update.
                    // This places process on GUI thread.
                    // Must use a delegate to pass arguments.
                    if (this.InvokeRequired)
                    {
                        this.BeginInvoke(new OnPositionUpdateDelegate(OnPositionUpdate), new object[] { oUpdate.Position });
                    }
                    else
                    {
                        OnPositionUpdate(oUpdate.Position);
                    }

                    break; // TODO: might not be correct. Was : Exit For

                }

            }
        }

    }

然后这个被调用

        private void OnPositionUpdate(T4.API.Position poPosition)
    {

        if (object.ReferenceEquals(poPosition.Market, moMarket))
        {

            // Display the position details.
            DisplayPosition(poPosition.Market, 1);
        }

    }

然后调用它来更新保存位置数的文本框

private void DisplayAccount(Account poAccount)
            {

                if ((moAccount != null))
                {

                    try
                    {
                        // Lock the host while we retrive details.
                        moHost.EnterLock("DisplayAccount");

                        // Display the current account balance.
                        txtCash.Text = String.Format("{0:#,###,##0.00}", moAccount.AvailableCash);

                    }
                    catch (Exception ex)
                    {
                        // Trace the error.
                        Trace.WriteLine("Error: " + ex.ToString());

                    }
                    finally
                    {
                        // Unlock the host object.
                        moHost.ExitLock("DisplayAccount");

                    }

                }

            }


            private void DisplayPosition(Market poMarket, int piID)
            {
                string strNet = "";
                string strBuys = "";
                string strSells = "";

                bool blnLocked = false;

                try
                {

                    if ((poMarket != null) && (moAccount != null))
                    {
                        // Lock the host while we retrive details.
                        moHost.EnterLock("DisplayPositions");

                        // Update the locked flag.
                        blnLocked = true;


                        // Temporary position object used for referencing the account's positions.
                        Position oPosition = default(Position);

                        // Display positions for current account and market1.

                        // Reference the market's positions.
                        oPosition = moAccount.Positions[poMarket.MarketID];

                        Trace.WriteLine("Inside of DisplayPosition: " + oPosition.ToString());

                        if ((oPosition != null))
                        {
                            // Reference the net position.
                            strNet = oPosition.Net.ToString();
                            strBuys = oPosition.Buys.ToString();
                            strSells = oPosition.Sells.ToString();

                            // this part is what I added
                           // this is an int value
                            _positionQuantity = oPosition.Net;

                        }

                        switch (piID)
                        {
                            case 1:
                                // Display the net position.
                                txtNetPosition.Text = strNet;
                                break;
                        }

                    }

                }
                catch (Exception ex)
                {
                    // Trace the error.
                    Trace.WriteLine("Error " + ex.ToString());

                }
                finally
                {
                    // Unlock the host object.
                    if (blnLocked)
                        moHost.ExitLock("DisplayPositions");

                }

            }

我注意到如果我从 Trace.WriteLine 调用 _positionQuantity,它不会更新。但是,当我从 MessageBox.Show(_positionQuantitiy) 调用它时,它会更新。

我的问题是我必须在没有 GUI 项目的情况下进行内部计算。如何更新 _positionQuantity 而无需从 GUI 事件类型的事物中调用它,并在需要时更新它

谢谢 斯宾塞

【问题讨论】:

    标签: c# multithreading user-interface trading


    【解决方案1】:

    对 Windows 窗体控件的更新必须在创建它们的同一线程上进行。 (也就是说,它们具有线程亲和性。)要在 UI 线程上执行委托,请调用表单的 Invoke 方法,如下所示:

    myForm.Invoke(() => {
                            doThis(someControl);
                            doThat(anotherControl);
                            doTheOther(anotherControl, 42);
                        });
    

    花括号中的内容称为匿名方法。当然,单行也可以:

    myForm.Invoke(() => {someControl.Text = "Threads!";});
    

    如果您想立即更新表单的视觉状态,可以使用theForm.Refresh();

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多