gpt4 book ai didi

c# - 异步线程未发布

转载 作者:行者123 更新时间:2023-11-30 17:04:50 27 4
gpt4 key购买 nike

我在使用 C#/.NET 4 中的异步方法时遇到问题。它向 w3wp 进程添加线程,但不释放它们。我们的服务器最终达到 400 左右的线程限制,然后应用程序池在回收时变得无法访问。

我们在这里使用 EndInvoke 是不是错了?

这是一个重现问题的简化示例:

    [WebMethod]
public void Test()
{
TestFind("test");
}

private delegate void TestFindDelegate(String val);
private TestFindDelegate tfd;
private IAsyncResult iar;

public void TestFind(String val)
{
try
{
tfd = new TestFindDelegate(this.TestFindAsync);
iar = tfd.BeginInvoke(val, null, null);
}
catch (Exception ex)
{
String msg = ex.Message;
}
}

//Method runs asynchronously
private void TestFindAsync(String val)
{
try
{
//Run stuff here
}
catch (Exception ex)
{
String msg = ex.Message;
}
finally
{
tfd.EndInvoke(iar); //clean up resources
}
}

重现步骤:
1. 将上面的代码添加到一个 web service.asmx
2.打开任务管理器,添加线程一栏,找到进程
3. 打开Fiddler,进入Composer,输入web service url/Test
4.点击执行20-40次
5. 观察进程中的线程数增加,但没有减少。

最佳答案

问题很可能是您没有正确调用 EndInvoke。使用 Delegate.BeginInvoke 时,您必须始终调用 EndInvoke,并且必须您的方法完成后调用它。来自 MSDN :

No matter which technique you use, always call EndInvoke to complete your asynchronous call.

现在,您正在跟踪变量中的 tfdiar,但每次调用都会覆盖该变量。因此,如果您快速调用它 100 次,您将只调用一次 EndInvoke

更好的选择是只使用 Task 来运行它:

public void TestFind(String val)
{
Task.Factory.StartNew(() => this.TestFindAsync(val));
}

这将在线程池线程上调用它,但不需要 EndInvoke 调用,也不需要保存任何局部变量。

关于c# - 异步线程未发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17076694/

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