gpt4 book ai didi

c# - 异步运行同步方法的正确方法是什么

转载 作者:行者123 更新时间:2023-11-30 21:43:25 25 4
gpt4 key购买 nike

我有一个抽象类,它的方法是这样定义的

public abstract class FooBase : IDisposable
{
protected abstract bool GetData(params object[] getDataParams);
}

我正在像这样使用这个抽象类并尝试异步运行 GetData 方法

public class SomeClass : FooBase
{
protected override bool GetData(params object[] getDataParams)
{
var task = Task.Factory.StartNew(() =>
{
using (var adapter = new DataAdapter())
{
// Take your time and fetch the data
}
});
task.Wait();
return true;
}
}

我想弄清楚的是:我这样做是对还是错,或者是否有任何其他更好的方法来实现相同的目标。

更新

如果我像这样改变我的方法,它会不会被异步调用

public class SomeClass : FooBase
{
protected override bool GetData(params object[] getDataParams)
{
var task = Task.Factory.StartNew(async () =>
{
using (var adapter = new DataAdapter())
{
// Take your time and fetch the data
}
});
task.Wait();
return true;
}
}

感谢您对此的评论。

最佳答案

除了同步之外,没有其他方法可以运行同步方法。

您可以将结果包装在看起来像是异步运行的东西中(例如 Task.FromResult ),或者在另一个线程中运行。1 但是同步方法仍然会阻塞它所在的线程继续运行。

(相反,阻塞异步操作是微不足道的。这就是为什么你需要让底层操作异步,因为你可以在上面构建同步和异步方法。)

更新(针对有问题的更新):

那个额外的代码——特别是 task.Wait() statement – 将导致调用者的线程在等待任务完成时阻塞。该任务将在另一个线程上运行,导致该线程阻塞。 IE。您正在导致两个线程(调用者和线程池线程)阻塞。如果直接调用底层方法,则只会阻塞调用者的线程。

您有两种方法:

  1. 最佳:使用 ADO.NET 的异步操作。 (这意味着不使用 DataTables/DataAdaptor 但恕我直言,这无论如何都是一个好举动:他们所做的只是将应该在数据库上完成的操作转移到客户端。)

  2. 卸载到另一个线程,但返回 Task<TResult>给调用者,只标记 Task as complete 那么底层操作就完成了。像这样的东西:

    protected override Task<bool> GetData(params object[] getDataParams) {
    var tcs = new TaskCompletionSource<bool>();
    Task.Factory.StartNew(async () => {
    using (var adapter = new DataAdapter()) {
    // Take your time and fetch the data
    tcs.SetResult(the-result);
    }
    });
    return tcs.Task;
    }

    注意这里返回自 GetDataTask<bool> :调用者需要等待或并发做其他事情,然后得到数据操作的结果。如果调用者只是等待,那么你有两个阻塞的线程。 (C# 5 的 await 不同:调用者也变为异步。)


1 为了避免疑义:这可以看起来像一个正常的,Task<T>返回,异步方法(例如,利用 TaskCompletionSource<T> 将阻塞从当前线程加载到线程池中的某个线程)。但它仍然是一个阻塞操作:只是阻塞了一个不同的线程。

关于c# - 异步运行同步方法的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41716126/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com