diff --git a/src/NTwain/DataTransferredEventArgs.cs b/src/NTwain/DataTransferredEventArgs.cs
new file mode 100644
index 0000000..87e4c79
--- /dev/null
+++ b/src/NTwain/DataTransferredEventArgs.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Buffers;
+
+namespace NTwain
+{
+ public class DataTransferredEventArgs : EventArgs, IDisposable
+ {
+ ///
+ /// Ctor for pooled data and the pool to clean it up.
+ ///
+ ///
+ ///
+ internal DataTransferredEventArgs(ArrayPool? pool, byte[]? data)
+ {
+ _pool = pool;
+ Data = data;
+ }
+
+
+ bool _disposed;
+ private readonly ArrayPool? _pool;
+
+ ///
+ /// The complete file data if the transfer was done
+ /// through memory. IMPORTANT: The data held
+ /// in this array will no longer be valid once
+ /// this event arg has been disposed.
+ ///
+ public byte[]? Data { get; private set; }
+
+
+
+ public void Dispose()
+ {
+ if (!_disposed)
+ {
+ if (_pool != null && Data != null)
+ {
+ _pool.Return(Data);
+ Data = null;
+ }
+ _disposed = true;
+ }
+ }
+ }
+}
diff --git a/src/NTwain/TwainAppSession.Xfers.cs b/src/NTwain/TwainAppSession.Xfers.cs
index f937ce8..850094b 100644
--- a/src/NTwain/TwainAppSession.Xfers.cs
+++ b/src/NTwain/TwainAppSession.Xfers.cs
@@ -1,6 +1,7 @@
using NTwain.Data;
using NTwain.Triplets;
using System;
+using System.Buffers;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
@@ -12,6 +13,12 @@ namespace NTwain
partial class TwainAppSession
{
+ // experiment using array pool for things transferred in memory.
+ // this can pool up to a "normal" max of legal size paper in 24 bit at 300 dpi (~31MB)
+ // so the array max is made with 32 MB. Typical usage should be a lot less.
+ static readonly ArrayPool XferMemPool = ArrayPool.Create(32505856, 4);
+
+
///
/// Start the transfer loop.
/// This should be called after receiving