|
Rank: Newbie Groups: Member
Joined: 11/29/2011 Posts: 4
|
I am testing implementing the EO.Pdf.HtmlToPdf in a webapplication.
However it appears that it's not threadsafe. I was weary when I saw the only way to access it was through a static method, so I set out to test it. I throw 6 threads at a time at it and rather consistently it throws an exception.
I am seeing both:
[System.IO.EndOfStreamException]{"Unable to read beyond the end of the stream."}
it occurs at: at System.IO.__Error.EndOfFile() at System.IO.MemoryStream.InternalReadInt32() at System.IO.BinaryReader.ReadInt32() at EO.Pdf.Internal.bb.a(Byte[] A_0, Single A_1, Single A_2, Single A_3, Single A_4, Double A_5, Double A_6) at EO.Pdf.Internal.km.a(String A_0, Boolean A_1, String A_2) at EO.Pdf.Internal.km.a()
as well as:
[System.ArgumentNullException]{"Buffer cannot be null.\r\nParameter name: buffer"}
it occurs at: at System.IO.MemoryStream..ctor(Byte[] buffer, Boolean writable) at System.IO.MemoryStream..ctor(Byte[] buffer) at EO.Pdf.Internal.bb.a(Byte[] A_0, Single A_1, Single A_2, Single A_3, Single A_4, Double A_5, Double A_6) at EO.Pdf.Internal.km.a(String A_0, Boolean A_1, String A_2) at EO.Pdf.Internal.km.a()
I'm certainly not an expert on this stuff, but I am sure that I'm passing a unique instance of the MemoryStream to the the converter and the second error looks like a constructor call that's outside my control anyway.
Has anyone else run into this, or is there are way to use the EO.Pdf.HtmlToPdf other than the static methods?
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
EO.Pdf is designed to be multithread safe on static members. If you call instance methods across multithread, then you need to synchronize in your code. If you see anything that does not work this way, try to create a test project and we will be happy to take a look.
Thanks
|
|
Rank: Newbie Groups: Member
Joined: 11/29/2011 Posts: 4
|
Ok. I will try to do this later. I've been doing more testing, It is clearly having issues with threadsafety. It only seems to trigger if the requests are <100ms apart. It is prior to the internal flow control because setting the Options to limit max requests doesn't affect the error. This afternoon I'll strip my specific code from my unit test and post the example.
|
|
Rank: Newbie Groups: Member
Joined: 11/29/2011 Posts: 4
|
Here is an example of what I was running. You can cut and paste this into a project that has EO.PDF and nUnit to see what I am talking about. If you don't have nUnit in the project you can simply remove the assertions and inline the testdelegate and you still see the behavior I am talking about.
Code: C#
[Test]
public void testConcurrency()
{
//Arrange
bool errorOccured = false;
object errorLock = new object();
string html = "<html><head></head><body>This Is Html!</body></html>";
Action testCall = () =>
{
try {
string htmlcopy = html.Substring(0);
MemoryStream stream = new MemoryStream();
EO.Pdf.HtmlToPdf.ConvertHtml(htmlcopy, stream);
}
catch (Exception e)
{
lock (errorLock) { errorOccured = true; }
throw e;
}
};
List<WaitHandle> handles = new List<WaitHandle>();
//Act
TestDelegate del = () =>
{
for (int j = 0; j < 50; j++)
{
for (int i = 0; i < 6; i++)
{
handles.Add(testCall.BeginInvoke(null, null).AsyncWaitHandle);
}
WaitHandle.WaitAll(handles.ToArray());
handles.Clear();
}
};
//Assert
Assert.DoesNotThrow(del);
Assert.IsFalse(errorOccured);
}
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
Thanks for the code. We were able to reproduce fix the problem. We are still doing some more testing and as soon as that is done, we should be able to provide you the new build. It should come either today or tomorrow.
Thanks!
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
We have posted a new build that should fix this issue. Please see your private message for the download location.
Thanks!
|
|
Rank: Newbie Groups: Member
Joined: 11/29/2011 Posts: 4
|
Thanks, that appears to have solved the threadsafety issue. But it introduced a new problem. The way it is determining the Page cutoffs appears to have broken in this build.
So the top quarter to half an inch of page 2 appears at the bottom of page one. This is new behavior that didn't occur in the previous build I had.
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
Can you post a test page so that we can take a look?
Thanks!
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,194
|
Hi,
The new build did change the paging algorithm from slightly above a text block’s top edge to exactly at the top of the text block’s top edge. This change was made because under certain scenarios adding additional space on top of the text line can cause other problems (for example, forcing table footer to the next page thus invalidates the previous calculated table layout). The change should not cause any problem for text because text lines are still honored. If it causes problem for you, please provide a sample and we will be happy to revisit the issue.
Alternatively, you can also apply “page-break-inside:avoid” on any element that you wish to avoid a page break.
Thanks!
|
|