Task.Wait 在不同的线程上 c#
Task.Wait on different thread c#
我有以下代码:
//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() 完成时响应。谢谢
OnBar() method takes 30 or more seconds.
如果在 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
}
我假设 OnBar
实际上不需要 30 秒才能 运行,它所做的是需要 30 秒才能 开始 在调用 ReqBarData 之后。如果那是真的,那么您真正拥有的是 Event-based Asynchronous Pattern, the easiest way to handle what you want to do is convert it to a Task-based Asynchronous Pattern.
因为您没有提供 Minimal, Complete, and Verifiable example 我将不得不对我认为您的程序的工作方式进行一些更改。如果您希望代码更接近您实际拥有的内容,则需要使用适当的示例更新您的问题。我假设 ReqBarData
有一个重载,它接受一个 object state
参数,该参数将传递给 OnBar
并且 OnBar
也传递了它是的对象列表等待。
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);
}
要在不锁定 UI 的情况下使用它,您只需调用函数并 await
使用 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;
}
我有以下代码:
//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() 完成时响应。谢谢
OnBar() method takes 30 or more seconds.
如果在 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
}
我假设 OnBar
实际上不需要 30 秒才能 运行,它所做的是需要 30 秒才能 开始 在调用 ReqBarData 之后。如果那是真的,那么您真正拥有的是 Event-based Asynchronous Pattern, the easiest way to handle what you want to do is convert it to a Task-based Asynchronous Pattern.
因为您没有提供 Minimal, Complete, and Verifiable example 我将不得不对我认为您的程序的工作方式进行一些更改。如果您希望代码更接近您实际拥有的内容,则需要使用适当的示例更新您的问题。我假设 ReqBarData
有一个重载,它接受一个 object state
参数,该参数将传递给 OnBar
并且 OnBar
也传递了它是的对象列表等待。
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);
}
要在不锁定 UI 的情况下使用它,您只需调用函数并 await
使用 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;
}