将BeginInvoke转换为async / await

时间:2015-09-04 01:44:11

标签: c# winforms async-await begininvoke

我有一个函数apiClient.OrderSend必须在“GUI”线程中调用,所以我创建了这个函数

   private void RunOnUIThread(Action action)
   {
        this.BeginInvoke(action);
   }

然后我有一个需要returnint这样的功能

    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;
    }

问题是AlgoSendOrderapiClient.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)
    }
}

1 个答案:

答案 0 :(得分:6)

使用异步方法在单独的线程中执行后台任务。请注意以下示例中的Task.Run:

async Task<int> AlgoSendOrderAsync(MT4Order order)
{
    int retVal = -1;

    //Doing this on another thread using Task.Run
    await Task.Run(() =>
    {
        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;
}

在UI线程上调用此方法,如下所示:

async void onButtonClickOnWhatever(object sender, EventArgs args)
{
    int result = await AlgoSendOrderAsync(order);
    //Here you are on the UI thread, you can update your controls here safely
}