【发布时间】:2016-04-29 05:56:50
【问题描述】:
我有一个函数apiClient.OrderSend 必须在“GUI”线程内调用,所以我创建了这个函数
private void RunOnUIThread(Action action)
{
this.BeginInvoke(action);
}
然后我有一个函数需要像这样 return 和 int
int AlgoSendOrder(MT4Order order)
{
int retVal = -1;
RunOnUIThread(() =>
{
retVal = apiClient.OrderSend(order.Symbol, (TradeOperation)order.OrderSide, order.Volume,
order.Price, order.AllowedSlippage ?? default(int),
order.PriceToStopLoss ?? default(double),
order.PriceToTakeProfit ?? default(double));
});
return retVal;
}
问题是AlgoSendOrder在apiClient.OrderSend返回之前返回,所以retVal对于这个函数的客户端总是-1。
看来这个合理的改变是使用await-async对在GUI线程中执行函数,并达到预期的等待返回值的效果。但是我似乎无法让它工作。
看来我应该可以重做RunOnUIThread 以使用async-await
public async Task RunOnUIThreadAsync()
{
if (InvokeRequired)
{
// what do I put here?
}
{
… // like before (but can now use `await` expressions)
}
}
【问题讨论】:
-
在 UI 线程上运行阻塞任务(需要很长时间)似乎违反直觉。是否可以在后台运行 API 调用并在 API 调用返回后单独更新 UI?
-
@Phillipe,是的 winform,但调用者不能保证在 GUI 线程上,因此 begininvoke 的包装
-
@Onots,没有 apiclient.OrderSend 在 GUI 线程外崩溃。此外,整个过程不到 1 毫秒。
标签: c# winforms async-await begininvoke