加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – WPF应用程序中的线程抛出System.OutOfMemoryException

发布时间:2020-12-15 20:58:00 所属栏目:百科 来源:网络整理
导读:当应用程序执行处理以显示进度窗口时,以下代码将调用另一个线程.在我们多次执行后会抛出异常,例如命中次数超过50次. 这是我们的代码 – 从异常抛出的BusyIndi??catorHelper.ShowProgWindowCustomSize并将调用以下代码. public void ShowBusyIndicatorCustomS
当应用程序执行处理以显示进度窗口时,以下代码将调用另一个线程.在我们多次执行后会抛出异常,例如命中次数超过50次.
这是我们的代码 – 从异常抛出的BusyIndi??catorHelper.ShowProgWindowCustomSize并将调用以下代码.

public void ShowBusyIndicatorCustomSize(string message,WindowCustom currentWindow,bool fileTransferStatus = false)
{
    _message = message;
    using (_progressWindowWaitHandle = new AutoResetEvent(false))
    {
        _transferLoadVisibility = fileTransferStatus;
        //Starts the progress window thread
        Thread newprogWindowThread = new Thread(() => ShowProgWindowCustomSize(currentWindow));  
        //new Thread(new ThreadStart(ShowProgWindowNew(height,width,left,right)));
        newprogWindowThread.SetApartmentState(ApartmentState.STA);
        newprogWindowThread.IsBackground = true;
        newprogWindowThread.Start();

        //Wait for thread to notify that it has created the window
        _progressWindowWaitHandle.WaitOne();
        _isActive = true;
    }
}

这将调用ShowProgWindowCustomSize(currentWindow),如下所示.

private void ShowProgWindowCustomSize(WindowCustom currentWindow)
    {
        if (_transferLoadVisibility)
        {
            //creates and shows the progress window
            progWindow = new LoadingWindow(_message);
            progWindow.Height = currentWindow.WindowHeight;
            progWindow.Width = currentWindow.WindowWidth;
            progWindow.Left = currentWindow.WindowLeft;
            progWindow.Top = currentWindow.WindowTop;
            progWindow.WindowState = currentWindow.WindowState;

            progWindow.FileTansfer();
            progWindow.Show();
        }
        else
        {
            //creates and shows the progress window
            progWindow = new LoadingWindow(_message);
            progWindow.Height = currentWindow.WindowHeight;
            progWindow.Width = currentWindow.WindowWidth;
            progWindow.Left = currentWindow.WindowLeft;
            progWindow.Top = currentWindow.WindowTop;
            progWindow.WindowState = currentWindow.WindowState;
            progWindow.Show();
        }

        //makes sure dispatcher is shut down when the window is closed
        progWindow.Closed += (s,e) => Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);

        //Notifies command thread the window has been created
        _progressWindowWaitHandle.Set();

        //Starts window dispatcher
        System.Windows.Threading.Dispatcher.Run();
    }

以下是抛出的outofmemory异常.

Application: BioMedicalVerification.exe Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.OutOfMemoryException Stack: at
System.Windows.Media.Composition.DUCE+Channel.SyncFlush() at
System.Windows.Media.MediaContext.CompleteRender() at
System.Windows.Interop.HwndTarget.OnResize() at
System.Windows.Interop.HwndTarget.HandleMessage
(MS.Internal.Interop.WindowMessage,IntPtr,IntPtr) at
System.Windows.Interop.HwndSource.HwndTargetFilterMessage (IntPtr,
Int32,Boolean ByRef) at MS.Win32.HwndWrapper.WndProc
(IntPtr,Int32,Boolean ByRef) at
MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object) at
System.Windows.Threading.ExceptionWrapper.InternalRealCall
(System.Delegate,System.Object,Int32) at
System.Windows.Threading.ExceptionWrapper.TryCatchWhen (System.Object,
System.Delegate,System.Delegate) at
System.Windows.Threading.Dispatcher.LegacyInvokeImpl
(System.Windows.Threading.DispatcherPriority,System.TimeSpan,Int32) at
MS.Win32.HwndSubclass.SubclassWndProc(IntPtr,IntPtr)
at MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr,
IntPtr,IntPtr) at MS.Win32.HwndSubclass.DefWndProcWrapper(IntPtr,IntPtr) at
MS.Win32.UnsafeNativeMethods.CallWindowProc(IntPtr,IntPtr) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr,IntPtr) at MS.Win32.UnsafeNativeMethods.SetWindowPos
(System.Runtime.InteropServices.HandleRef,
System.Runtime.InteropServices.HandleRef,
Int32) at System.Windows.Window.SetupInitialState(Double,Double,
Double,Double) at System.Windows.Window.CreateSourceWindow(Boolean)
at System.Windows.Window.CreateSourceWindowDuringShow() at
System.Windows.Window.SafeCreateWindowDuringShow() at
System.Windows.Window.ShowHelper(System.Object) at
System.Windows.Window.Show() at
Org.Bestinet.BV.Presentation.UI.BusyIndicatorHelper.ShowProgWindowCustomSize
(Org.Bestinet.BV.Presentation.UI.WindowCustom) at
Org.Bestinet.BV.Presentation.UI.BusyIndicatorHelper+<>
c__DisplayClass2.<ShowBusyIndicatorCustomSize>b__0() at
System.Threading.ThreadHelper.ThreadStart_Context(System.Object) at
System.Threading.ExecutionContext.RunInternal
(System.Threading.ExecutionContext,System.Threading.ContextCallback,
System.Object,Boolean) at System.Threading.ExecutionContext.Run
(System.Threading.ExecutionContext,
System.Object) at System.Threading.ThreadHelper.ThreadStart()

我怀疑因为VerifyFinger功能,因为这是我们检查指纹图像的地方

BusyIndicatorHelper busyIndicatorHelper = new BusyIndicatorHelper();
List<WorkerDO> docList = new         
DatabaseHelper().SearchDocInfo(UserContext.VdrInfo.WorkerObj.WrkrId);

if (docList != null && docList.Count > 0)
{   busyIndicatorHelper.ShowBusyIndicatorCustomSize("Verification",WindowSetting.GetCurrentWindowState(this));

    FingerPrintHelper fp = null;
    if (_fpHelper != null)
       fp = _fpHelper;
    else
       fp = FingerPrintHelper.GetFingerPrinterHelperObj;

    verifyStatus = fp.VerifyFinger(docList,_viewModel.DetectedFingers,IsIndexFingerSelected);
    docList = null;
    _viewModel.DetectedFingers = null;
}

解决方法

为什么要关闭CurrentDispatcher?它是您程序中唯一的一个,您的代码永远不会执行关闭.因此,每次打开BusyWindow时,都会创建新线程(距离内存为1MB),并且它会进入无限循环,从而占用系统资源的另一部分.最终你的程序会从你的异常状态中脱离内存.

你真的不应该为你的任务开始一个新的线程 – 使用更高的抽象杠杆,可能是ThreadPoolTask Parallel Library.这将有助于消除代码中的内存泄漏.

更新:
我在你的新代码中看到这样一句话:

_viewModel.DetectedFingers = null;

我怀疑这是你从客户那里得到的Image.如果是这样,你不能简单地将它设置为null,你必须Dispose()它来释放你的图形资源,如下所示:

verifyStatus = fp.VerifyFinger(docList,IsIndexFingerSelected);
docList = null;
_viewModel.DetectedFingers.Dispose();
_viewModel.DetectedFingers = null;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读