假设我使用了一个我无法访问其源代码的库,并且它具有以下方法之一:我将其称为类型A,B和C
A型:
public async Task FakeAsyncMethod1()
{
await Task.Run(() =>
{
// Some synchronous CPU-bound work.
Thread.Sleep(1000);
});
}
B类:
public async Task<string> FakeAsyncMethod2()
{
string result = await Task.Run(() =>
{
// Some synchronous IO-bound work.
var request = (HttpWebRequest)WebRequest.Create("someURL");
using (var stream = request.GetResponse().GetResponseStream())
using (var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
});
return result;
}
C型:
public async Task<string> RealAsyncMethod()
{
HttpClient client = new HttpClient();
// Some asynchronous IO-bound work.
var responseMsg = await client.GetAsync("someURL");
return await responseMsg.Content.ReadAsStringAsync();
}
现在,我并不期望能够区分A型和B型。它们都在Task.Run
中包含了一些同步工作,我认为它不受CPU限制或IO绑定的影响。
所以,我的问题是:
如果库的开发人员使用了type-A或type-B,那么这将是一个非常糟糕的实现,是否有办法判断一个方法是否是C型(完全异步)?
另外,假设我们有一个类似于B型(或A)的方法,但阻塞代码甚至不包含在Task.Run
中,有没有办法确定它是阻塞方法(阻止当前线程)?当然,我可以手动检查它是否阻止了UI线程(例如,在WinForms应用程序中),但我想知道是否有更好的方法来做到这一点(也许, 编程 )。
编辑:我没有寻找涉及分析代码的解决方案(例如,可以建议使用反编译器等)。有时源代码甚至可用,但我不会因为某种原因检查它。
我正在寻找的是通过运行代码并分析其行为来直接解决问题的方法(例如,分析线程等,我不知道如何),我想知道这是否可能。
答案 0 :(得分:0)
我不是100%确定我在下面所说的内容,但即使错误或不完整也可能是一个很好的起点。
由于方法A和方法B阻塞线程池的线程(虽然完全异步方法没有),只要你控制进程创建的线程,就可以在不同的时间比较线程池中的可用线程T1 T2。
我创建了一个简单的例子:
static void Main(string[] args)
{
var t = MainAsync(args);
t.Wait();
Console.ReadKey();
}
static async Task MainAsync(string[] args)
{
int availableThreadT1;
int availableAsyncIOThreadT1;
int availableThreadT2;
int availableAsyncIOThreadT2;
ThreadPool.GetAvailableThreads(out availableThreadT1, out availableAsyncIOThreadT1);
//var t1 = FakeAsync(); //Locked thread 1
var t2 = RealAsync(); //Locked thread 0
ThreadPool.GetAvailableThreads(out availableThreadT2, out availableAsyncIOThreadT2);
//Console.Write($"Locked threads from FakeAsync {availableThreadT1 - availableThreadT2} \r\n");
Console.Write($"Locked threads from RealAsync {availableThreadT1 - availableThreadT2} \r\n");
}
static async Task FakeAsync()
{
var t = Task.Run(() =>
{
Thread.Sleep(1000);
});
await t;
}
static async Task RealAsync()
{
var t = Task.Delay(1000);
await t;
}