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