Async DIME call seem to drop randomly

B

Bob

I have a web service using WSE 1.0SP DIME attachment to transfer files in
production. The synchronous call works great and pretty stable. I have
been trying to add the asyncrhonous calls. On the surface it works but then
I realized that when multiple async calls are made to the server in a loop,
some callbacks never happen (no exception either). Here's a piece of
simplified test code on the client side (Windows app) below. Everytime the
button click event is fired, anywhere from 1 to all the files may be
transferred. I'm suspecting some of the callbacks are colliding but don't
know how to check.

........................
private AsyncDime _svc; //AsyncDime is the WS proxy class.

//Windows Form button click event handler, this starts the async file
get process.
//This test trys to get 4 files from the server by giving the file
names.
private void btnGetFileAsync_Click(object sender, System.EventArgs e) {
string[] fns = new string[] {"BobTestFile.txt", "BobTestFile1.txt",
"BobTestFile2.txt", "BobTestFile3.txt"};
this._svc = new AsyncDime();
foreach (string fn in fns) {
AsyncCallback acb = new
AsyncCallback(this.RetrievalDoneCallback);
this._svc.BeginGetFile(fn, acb, this._svc);
}
}

//Handles the call back.
private void RetrievalDoneCallback(IAsyncResult returnValue) {
AsyncDime fileService = (AsyncDime)returnValue.AsyncState;
fileService.EndGetFile(returnValue);
string fileNameFrAttachment =
this.SaveAttachment(fileService.ResponseSoapContext.Attachments[0]);
}

//Save the attachement to a file
private string SaveAttachment(DimeAttachment da) {
int len;
byte[] chunk = new Byte[256];
System.IO.FileStream fs;
System.IO.Stream st;
string fileName = da.Id;
st = da.Stream;
fs = File.Open( @"c:\temp\" + fileName, FileMode.OpenOrCreate,
FileAccess.Write);
while ((len = st.Read(chunk, 0, chunk.Length)) > 0) {
fs.Write(chunk, 0, len);
}
st.Close();
fs.Close();
return fileName;
}
 
G

Govind Ramanathan

Hi Bob,
What is the effect you are seeing? The SaveAttachment method is not thread
safe. It might be a problem with that. How did you figure out that the
recalls didn't happen? Please provide some more information.


Govind
 
B

Bob

When I was doing testing I noticed some files are not saved to the file
system on the client side (that is, out of the 4 files, only 2 or 3 show up
in the result folder), and it seems random which files are not saved.

Could you provide a bit more detail on why the SaveAttachment() method is
not thread-safe and what can be done to make it so? I did notice that the
very first file transferred to the client side ends up being used by some
process (so it can be copied or moved) for a while. That may have something
to do with what you are saying.

Thanks for the help
Bob

Govind Ramanathan said:
Hi Bob,
What is the effect you are seeing? The SaveAttachment method is not thread
safe. It might be a problem with that. How did you figure out that the
recalls didn't happen? Please provide some more information.


Govind

Bob said:
I have a web service using WSE 1.0SP DIME attachment to transfer files in
production. The synchronous call works great and pretty stable. I have
been trying to add the asyncrhonous calls. On the surface it works but then
I realized that when multiple async calls are made to the server in a loop,
some callbacks never happen (no exception either). Here's a piece of
simplified test code on the client side (Windows app) below. Everytime the
button click event is fired, anywhere from 1 to all the files may be
transferred. I'm suspecting some of the callbacks are colliding but don't
know how to check.

........................
private AsyncDime _svc; //AsyncDime is the WS proxy class.

//Windows Form button click event handler, this starts the async file
get process.
//This test trys to get 4 files from the server by giving the file
names.
private void btnGetFileAsync_Click(object sender, System.EventArgs
e)
{
string[] fns = new string[] {"BobTestFile.txt", "BobTestFile1.txt",
"BobTestFile2.txt", "BobTestFile3.txt"};
this._svc = new AsyncDime();
foreach (string fn in fns) {
AsyncCallback acb = new
AsyncCallback(this.RetrievalDoneCallback);
this._svc.BeginGetFile(fn, acb, this._svc);
}
}

//Handles the call back.
private void RetrievalDoneCallback(IAsyncResult returnValue) {
AsyncDime fileService = (AsyncDime)returnValue.AsyncState;
fileService.EndGetFile(returnValue);
string fileNameFrAttachment =
this.SaveAttachment(fileService.ResponseSoapContext.Attachments[0]);
}

//Save the attachement to a file
private string SaveAttachment(DimeAttachment da) {
int len;
byte[] chunk = new Byte[256];
System.IO.FileStream fs;
System.IO.Stream st;
string fileName = da.Id;
st = da.Stream;
fs = File.Open( @"c:\temp\" + fileName, FileMode.OpenOrCreate,
FileAccess.Write);
while ((len = st.Read(chunk, 0, chunk.Length)) > 0) {
fs.Write(chunk, 0, len);
}
st.Close();
fs.Close();
return fileName;
}
 
B

Byron Kim

This is thread safety issue. You should use separate proxy in calling each
asynchronous call.

thanks
Byron KIM
 
B

Bob

Hmm, I think you are right. Thanks a lot. I changed the moved the code to
create the proxy into the loop so everytime it's a new instance. I tried a
few times and everytime it's getting all the files. So the new code to
begin the call is below. The async call is not very efficient then. If I
have a very large number of files, it would end up creating so many
instances.

private void btnGetFileAsync_Click(object sender, System.EventArgs e) {
string[] fns = new string[] {"BobTestFile.txt",
"BobTestFile1.txt","BobTestFile2.txt", "BobTestFile3.txt"};
foreach (string fn in fns) {
AsyncCallback acb = new
AsyncCallback(this.RetrievalDoneCallback);
this._svc = new AsyncDime();
this._svc.BeginGetFile(fn, acb, this._svc);
}
}


Byron Kim said:
This is thread safety issue. You should use separate proxy in calling each
asynchronous call.

thanks
Byron KIM

Bob said:
I have a web service using WSE 1.0SP DIME attachment to transfer files in
production. The synchronous call works great and pretty stable. I have
been trying to add the asyncrhonous calls. On the surface it works but then
I realized that when multiple async calls are made to the server in a loop,
some callbacks never happen (no exception either). Here's a piece of
simplified test code on the client side (Windows app) below. Everytime the
button click event is fired, anywhere from 1 to all the files may be
transferred. I'm suspecting some of the callbacks are colliding but don't
know how to check.

........................
private AsyncDime _svc; //AsyncDime is the WS proxy class.

//Windows Form button click event handler, this starts the async file
get process.
//This test trys to get 4 files from the server by giving the file
names.
private void btnGetFileAsync_Click(object sender, System.EventArgs
e)
{
string[] fns = new string[] {"BobTestFile.txt", "BobTestFile1.txt",
"BobTestFile2.txt", "BobTestFile3.txt"};
this._svc = new AsyncDime();
foreach (string fn in fns) {
AsyncCallback acb = new
AsyncCallback(this.RetrievalDoneCallback);
this._svc.BeginGetFile(fn, acb, this._svc);
}
}

//Handles the call back.
private void RetrievalDoneCallback(IAsyncResult returnValue) {
AsyncDime fileService = (AsyncDime)returnValue.AsyncState;
fileService.EndGetFile(returnValue);
string fileNameFrAttachment =
this.SaveAttachment(fileService.ResponseSoapContext.Attachments[0]);
}

//Save the attachement to a file
private string SaveAttachment(DimeAttachment da) {
int len;
byte[] chunk = new Byte[256];
System.IO.FileStream fs;
System.IO.Stream st;
string fileName = da.Id;
st = da.Stream;
fs = File.Open( @"c:\temp\" + fileName, FileMode.OpenOrCreate,
FileAccess.Write);
while ((len = st.Read(chunk, 0, chunk.Length)) > 0) {
fs.Write(chunk, 0, len);
}
st.Close();
fs.Close();
return fileName;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top