gpt4 book ai didi

c# - 泄漏 Web 服务完成事件?

转载 作者:太空宇宙 更新时间:2023-11-03 16:09:50 25 4
gpt4 key购买 nike

在我的 C# 应用程序中,我有一个服务引用,我在其中一遍又一遍地执行相同的调用。

void GetData()
{
var request = new GetDataRequest { someData = "blabla" } ;
service.GetDataCompleted += (sender, args) =>
{
// do something; i'm afraid that this is executed multiple times, as GetData() is called multiple times
}
service.GetDataAsync(request);
}

void GetData2()
{
var request = new GetDataRequest { someData = "blabla2" } ;
service.GetDataCompleted += (sender, args) =>
{
// do something different here!
}
service.GetDataAsync(request);
}

我怀疑这会以某种方式泄漏,因为我每次都注册一个新的事件处理程序。这是真的吗?如果是,我该如何避免?

最佳答案

你可以这样做:

void GetData()
{
var request = new GetDataRequest { someData = "blabla" } ;

EventHandler handler = null;
handler = (sender, args) =>
{
// do something; i'm afraid that this is executed multiple times, as GetData() is called multiple times

//remove itself
service.GetDataCompleted -= handler;
};

service.GetDataCompleted += handler;
service.GetDataAsync(request);
}

void GetData2()
{
var request = new GetDataRequest { someData = "blabla2" } ;
EventHandler handler = null;

handler = (sender, args) =>
{
// do something different here!

//remove itself
service.GetDataCompleted -= handler;
};

service.GetDataCompleted += handler;
service.GetDataAsync(request);
}

编辑:关于仅将调用同步到其处理程序:如果您调用 GetData2() 后立即调用 GetData(),您将无法预测上面代码的结果。大多数情况下,两个处理程序都会被两个请求调用。

最简单的解决方案是为每个 GetDataX() 方法提供单独的 service 代理对象。这样您就可以同时发出两个请求。

但是,如果您被迫只使用一个代理对象,并发出并发请求 - 可能会调用错误的处理程序。一种选择是您可以使用 UserState 对象来识别您的请求,这样即使调用了错误的处理程序,它也可以检测到它是为错误的请求调用的。

void GetData()
{
var request = new GetDataRequest { someData = "blabla" } ;

Guid userState = Guid.NewGuid();

EventHandler<GetDataCompletedEventArgs> handler = null;
handler = (sender, args) =>
{
if (userState.Equals(args.UserState))
{
// do something; i'm afraid that this is executed multiple times, as GetData() is called multiple times

//remove itself
service.GetDataCompleted -= handler;
}
};

service.GetDataCompleted += handler;
service.GetDataAsync(request, userState);
}

void GetData2()
{
var request = new GetDataRequest { someData = "blabla2" } ;

Guid userState = Guid.NewGuid();

EventHandler<GetDataCompletedEventArgs> handler = null;
handler = (sender, args) =>
{
if (userState.Equals(args.UserState))
{
// do something different here!

//remove itself
service.GetDataCompleted -= handler;
}
};

service.GetDataCompleted += handler;
service.GetDataAsync(request, userState);
}

现在,如果您发出并发请求,即使两个请求都调用了两个处理程序,也只有正确请求的正确代码才会在 if 条件下运行。

如果您不想使用 UserState,您可以通过一些方法来同步调用,这样处理程序就不会相互越过。以下是一种使用 Tasks 的非阻塞方式,可确保请求一个接一个地发生。

Task<GetDataResponse> GetData()
{
var src = new TaskCompletionSource<GetDataResponse>();

var request = new GetDataRequest { someData = "blabla" } ;
EventHandler handler = null;
handler = (sender, args) =>
{
// do something; i'm afraid that this is executed multiple times, as GetData() is called multiple times

src.SetResult(args.Result);

//remove itself
service.GetDataCompleted -= handler;
};

service.GetDataCompleted += handler;
service.GetDataAsync(request);

return src.Task;
}

Task<GetDataResponse> GetData2()
{
var src = new TaskCompletionSource<GetDataResponse>();

var request = new GetDataRequest { someData = "blabla2" } ;
EventHandler handler = null;

handler = (sender, args) =>
{
// do something different here!

src.SetResult(args.Result);

//remove itself
service.GetDataCompleted -= handler;
};

service.GetDataCompleted += handler;
service.GetDataAsync(request);

return src.Task;

}

并且在调用方法中,确保它们被一个接一个地调用:

GetData().ContinueWith( t => GetData2() );

关于c# - 泄漏 Web 服务完成事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17950172/

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