的任务.等待不同的线程c#

本文关键字:线程 任务 等待 | 更新日期: 2023-09-27 17:53:54

我有以下代码:

//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()完成。由于

的任务.等待不同的线程c#

我继续假设OnBar实际上不需要30秒来运行,它所做的是在调用ReqBarData后需要30秒才能。如果这是真的,你真正拥有的是一个基于事件的异步模式,那么处理你想做的事情的最简单方法就是将它转换为一个基于任务的异步模式。

因为你没有提供一个最小的,完整的,可验证的例子,我将不得不做一些改变,我认为你的程序是如何工作的。你需要更新你的问题与一个适当的例子,如果你想代码更接近你真正拥有的。我假设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的情况下使用它,只需调用该函数并使用async/await 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;
}

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
}