我有一个 WCF 服务,我在某个方法中调用另一个方法,但是使用 Task.StartNew(.... 之后,WCF 方法返回并且客户端失去连接。
一切都很好,到目前为止。
在另一个线程的这个方法中,我使用 ImageMagick.NET x64 来调整 jpg 图像的大小。最后一次使用该服务时,我得到了一个带有以下 StackTrace 的 ThreadAbortException:
Message: 'System.Threading.ThreadAbortException: Thread was being aborted.
at Magick.Image.write(Image* , Blob* )
at ImageMagick.MagickWriter.Write(Image* image, Blob* blob)
at ImageMagick.MagickWriter.Write(Image* image, Stream stream)
at My.Libs.MyService.Sync.Actions.ResizeAction.ExecuteAction(Stream sourceStream)
另一个也出现了:
Message: 'System.Threading.ThreadAbortException: Thread was being aborted.
at Magick.Image.resize(Image* , Geometry* )
at ImageMagick.MagickImage.Resize(MagickGeometry geometry)
at My.Libs.MyService.Sync.Actions.ResizeAction.ExecuteAction(Stream sourceStream)
所以一次是 Image.Resize 方法,另一次是 Image.Write 方法。
但大多数时候,代码运行得很好。
我的问题:这些某些方法是否明显导致异常,然后导致 ThreadAbortException?或者是否有可能,来自 IIS / WFF 的预期来自 IIS / WFF,它中止了操作(例如应用程序池回收、执行超时过期等?我应该从哪里开始调查?
更新:我 StartNew 没有等待,所以调用将很快完成,只有任务正在运行(或应该),直到他完成哈希,代码:
// Start method
Task.Factory
.StartNew(() => this.Sync(0, syncTaskStatus))
.ContinueWith(task => blSyncTaskInstance.SetFinished(syncTaskId));
// End method
就是现在...
Task.Factory
.StartNew(() => this.Sync(0, syncTaskStatus), TaskCreationOptions.LongRunning)
.ContinueWith(task => blSyncTaskInstance.SetFinished(syncTaskId));
更新二 - 错误出现的代码片段和服务内容
public Stream ExecuteAction(Stream sourceStream)
{
var memoryStream = new MemoryStream();
try
{
using (MagickImage image = new MagickImage(sourceStream))
{
int targetWidth = this._width;
int targetHeight = this._height;
string geometryString;
if (targetWidth == 0)
{
geometryString = "x" + targetHeight.ToString();
}
else if (targetHeight == 0)
{
geometryString = targetWidth.ToString();
}
else
{
throw new Exception(
string.Format(
"Weder die Höhen oder, noch die Breitenangabe ist 0, was bei ResizeAction der Fall sein muss! Width: '{0}', Height: '{1}'",
targetWidth, targetHeight));
}
var resizeGeometry = new MagickGeometry(geometryString);
image.Resize(resizeGeometry);
// Auf Wunsch progressiv rendern.
if (this._renderProgressive)
{
image.Interlace = Interlace.Line;
}
// Alle Bildprofile und Kommentare löschen.
image.Strip();
// Behebt falsche DPI Angabe mit Division durch Null in Crystal Reports.
image.Density = new MagickGeometry(300, 300);
image.Write(memoryStream);
}
}
catch (Exception ex)
{
sourceStream.Dispose();
LogService.Logger.Log(string.Format("ResizeAction failed, message: {0}", ex.Message), LogLevel.Error, ex);
throw;
}
return memoryStream;
}
这是调用 ExecuteAction 的代码:
private Stream GetStreamChainResult(Stream sourceStream, List<IAction> preCopyActions)
{
Stream workingStream = sourceStream;
foreach (var action in preCopyActions)
{
workingStream = action.ExecuteAction(workingStream);
workingStream.Position = 0;
}
return workingStream;
}
此致。