2012-04-13 69 views
0

此代码极其冻结了WPF应用程序。代码冻结了我的应用程序

有没有机会解决它?

var getScreenshot = Task.Factory.StartNew(() => 
{      
    Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new ThreadStart(() => {       
    #region Main 
    try 
    { 
     Graphics gfx; 
     Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); 
     gfx = Graphics.FromImage(bmp); 
     WindowInteropHelper windowInteropHelper = new WindowInteropHelper(this); 
     Screen screen = Screen.FromHandle(windowInteropHelper.Handle); 
     gfx.CopyFromScreen(screen.Bounds.X, screen.Bounds.Y, 0, 0, screen.Bounds.Size, CopyPixelOperation.SourceCopy); 
     MemoryStream ms = new MemoryStream(); 
     byte[] bitmapData = null; 
     using (bmp) 
     { 
      bmp.SetResolution(72, 72); 
      ImageCodecInfo myImageCodecInfo; 
      myImageCodecInfo = GetEncoderInfo("image/jpeg"); 
      System.Drawing.Imaging.Encoder myEncoder; 
      myEncoder = System.Drawing.Imaging.Encoder.Quality; 
      EncoderParameters encoderParameters = new EncoderParameters(); 
      EncoderParameter encoderParameter = new EncoderParameter(myEncoder, 25L); 
      encoderParameters.Param[0] = encoderParameter; 
      bmp.Save(ms, myImageCodecInfo, encoderParameters);        
      bitmapData = ms.ToArray(); 
     } 
     if (bitmapData != null) 
      DataProvider.UpdateScreen(((PlayerConfiguration)App.Current.Properties["PlayerConfig"]).InstallationKey, bitmapData); 
    } 
    catch (Exception ex) 
    { 
     #region Error 
     LogEntry l = new LogEntry(); 
     l.Message = string.Format("{0}", ex.Message); 
     l.Title = "GetScreen() Error"; 
     l.Categories.Add(Category.General); 
     l.Priority = Priority.Highest; 

     CustomLogger.WriteErrorLog(l, "GetScreen"); 

     #endregion 
    } 
    #endregion 
    })); 

}, TaskCreationOptions.LongRunning) 
.ContinueWith(x => x.Dispose()); 
+6

极度冻结?比'完全冻结'还要暖和吗? – 2012-04-13 18:53:40

+0

@MarcB:好笑:)但是要有礼貌 – Tigran 2012-04-13 18:57:25

+1

@MarcB冷的男人,很冷。 :) – 2012-04-13 19:01:04

回答

3

是的,只是不派遣到UI线程的整个事情。只需将最少量的代码放入Invoke调用中即可避免。它应该是当你实际更新UI时。由于整个事件都在代码中的invoke调用中,因此UI将被阻止,直到整个事情完成。

+0

请告诉我我必须将哪部分代码放入Invoke中?你能猜得到吗? – 2012-04-13 19:03:04

+0

@Peretz仔细看看你的代码,它似乎没有与我可以看到的控件进行交互,所以你根本不应该进入UI线程。如果在错误的线程中访问控件时出现错误,那么它会告诉你在“Invoke”调用中需要包装哪一行。 – Servy 2012-04-13 19:07:32

+0

我把一个INVOKE内的那些线-----> Dispatcher.BeginInvoke(DispatcherPriority.Render,新的ThreadStart(()=> { WindowInteropHelper windowInteropHelper =新WindowInteropHelper(本); 屏幕= Screen.FromHandle(windowInteropHelper。 Handle); gfx.CopyFromScreen(screen.Bounds.X,screen.Bounds.Y,0,0,screen.Bounds.Size,CopyPixelOperation.SourceCopy); })); ----------- |但它并没有帮助:( – 2012-04-13 19:20:48