在不从GUI调用事件的情况下,从GUI线程上的委托方法更新值



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

以下是一些代码:

声明来自API 的moAccount

internal AccountList moAccounts;

创建代理

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

在Init()内部,它注册

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

我相信这是在输入交易并更新头寸时调用的。头寸就像你在谷歌等公司的100股股票中一样,所以只有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);
}
}

然后调用它来更新保存位置数的TextBox

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事件类型调用它,并在需要时进行更新

谢谢Spencer

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

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

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

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

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

最新更新