우리는 클라이언트을 까지 확장하는 클라이언트 클래스를 보유하고 있습니다.이 경쟁 조건을 방지하는 방법은 무엇입니까?
protected void Proxy()
{
Error = null;
_proxy = new WebServiceClient<T>(_fullURL);
Error = _proxy.Error;
}
protected virtual void Cleanup()
{
if (_proxy != null)
{
_proxy.Dispose();
_proxy = null;
}
}
을 그리고 클라이언트 병렬로 호출되는 몇 가지 작업을 포함
BaseClass로이 방법이 있습니다. 클라이언트은 싱글 톤이 아니므로 매번 하나의 인스턴스를 생성합니다.
public void OperationAsync(Action<BaseResult> callback)
{
TaskCompletionSource<String> taskSrc = new TaskCompletionSource<String>();
Task<String> tsk = taskSrc.Task;
try
{
Proxy();
ThreadPool.QueueUserWorkItem(t =>
{
try
{
String result = _proxy.Channel.ExecuteOperation(SecurityToken());
taskSrc.SetResult(result);
}
catch (Exception ex)
{
taskSrc.SetException(ex);
}
});
tsk.Wait();
BaseResult r = new BaseResult();
r.Value = tsk.Result;
r.Error = tsk.Exception;
Cleanup();
if (callback != null)
{
callback(r);
}
}
catch (Exception ex)
{
FileManager.Log(ex);
}
}
당신이 볼 수 있듯이, 각각의 작업이 프록시 및 정리 작업을 호출
작업은 같다.
우리는 때때로 (어쩌면 하루에 한 번) 우리가 로그 파일에서이 오류를 참조 아직 행동의 패턴을 발견,하지만하지 않았다는 :
하나 이상의 오류가 발생 ..의 InnerException : System.ObjectDisposedException를 : 수 없다 배치 된 객체에 접근한다. 개체 이름 : 'System.ServiceModel.Channels.ServiceChannel'.
특정 작업에서는 발생하지 않습니다. 그것은 항상 변합니다. 프록시는 생성자와 처리 중에 수행해야한다고 생각하지만 여러 가지를 변경해야한다는 것을 의미하므로 확실하게 알고 싶습니다.
나는 그것을 개선 할 수있는 방법에 대해 정말로 감사 할 것입니다.
? 왜'Proxy'가'WebServiceClient'을 함수에 로컬 변수에 저장 한 다음 그 변수를'Cleanup'에 전달하지 않도록하십시오. 또한, 백그라운드 작업자는 함수 호출에 추가 오버 헤드를 추가하는 것 외에는 아무 것도하지 않습니다. 다른 스레드에 작업을 넣으려고한다면 immedatly 그 스레드에 대해'.Wait()'를 호출하면 끝난다. 그런 다음 여분의 스레드를 전혀 사용하지 않을 때 항상 성능이 저하 될 것이다. –
코드에서'catch (Exception ex)'를 쓰는 것을 정말로 중단해야합니다. 그냥 버그를 소개합니다. 복구 할 수있는 예외는 예외적 인 경우에만 잡아야합니다. [Eric Lippert의 Vexing Exceptions] (https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/)를 읽으십시오. – Enigmativity
여기에서 경쟁 조건을 얻으려면 동일한 인스턴스에서 여러 번 OperationAsync를 호출해야하며 (명령문에 따라 다르지는 않음) 정적 멤버로 _proxy를 사용해야합니다. 들). 따라서 경쟁 조건은 표시되지 않은 코드에서 실제로 다른 원인을 가진 것 같습니다 (즉, 개별 인스턴스에서 한 번 이상 OperationAsync를 호출). –