I am going on the assumption that OnBar
does not actaully take 30 seconds to run, what it does is it takes 30 seconds to start after calling ReqBarData. If that is true what you really have is a Event-based Asynchronous Pattern, the easiest way to handle what you want to do is convert it to a Task-based Asynchronous Pattern.
Because you did not provide a Minimal, Complete, and Verifiable example I am going to have to make some changes to how I think your program works. You will need to update your question with a proper example if you would like code closer to what you really have. I have made an assumption that ReqBarData
has a overload that takes in a object state
parameter which will be passed to OnBar
and OnBar
also gets passed the list of objects that it was waiting for.
public Task<List<Bar>> RequestDataAsync()
{
var tcs = new TaskCompletionSource<List<Bar>>();
//This does not need to be on a separate thread, it finishes fast.
CONNECTION.ReqBarData(tcs);
return tcs.Task;
}
virtual override void OnBar(List<Bar> someBars, object stateInfo)
{
//We get our TaskCompletionSource object back from the state paramter
var tcs = (TaskCompletionSource<List<Bar>>)stateInfo;
//we set the result of the task.
tcs.SetResult(someBars);
}
To use it without locking up the UI you simply call the function and await
it using async/await
public async void Button1_Click(object sender, EventArgs args)
{
await LoadData();
}
private async Task LoadData()
{
List<Bar> bars = await myConnectionClass.RequestDataAsync();
SomeBinding.DataSource = bars;
}