我有以下代码:
//requests bar data
Task.Run( () => CONNECTION.ReqBarData()).Wait();
//the bars arrive on different thread here
virtual override void OnBar()
{
//takes a while till all bars arrive
}
问题是我需要等待所有栏到达OnBar()方法,上面的代码只等待对ReqBarData()的调用。换句话说,ReqBarData()只需要几毫秒,但OnBar()方法需要30秒或更长时间。我还希望我的UI能够在我等待OnBar()完成时做出响应。谢谢
答案 0 :(得分:0)
OnBar()方法需要30秒或更长时间。
如果在UI线程中调用此方法,那么您可以使用Task.Run
在其他线程中运行它(类似于您已经执行的操作,因此我的评论不清楚,如果这是案例)。
更改
virtual override void OnBar()
{
... whatever
}
到
virtual override void OnBar() => Task.Run(() =>
{
... whatever
});
但更有可能只需使用async
:
async void SomeEventHandlerToExampleButtonClick(object sender, SomeEventArgs e)
{
await Task.Run(() => CONNECTION.ReqBarData());
... // you are here after ReqBarData() is finished and you are not blocking UI so far
}
答案 1 :(得分:0)
我假设$user
不会花费30秒的时间来运行,它的作用是在呼叫后 启动 需要30秒ReqBarData。如果这是真的,你真正拥有的是Event-based Asynchronous Pattern,处理你想要做的事的最简单方法是将其转换为Task-based Asynchronous Pattern。
因为您没有提供Minimal, Complete, and Verifiable example我将不得不对我认为您的程序的工作方式进行一些更改。如果您希望代码更接近您真正拥有的代码,则需要使用适当的示例更新您的问题。我假设OnBar
有一个带有ReqBarData
参数的重载,该参数将传递给object state
并且OnBar
也会传递给它的对象列表等待。
OnBar
要在不锁定UI的情况下使用它,只需使用async / await调用该函数并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);
}
await