2015-11-04 43 views
2

在visual studio 2015社区中使用c#,尝试将转换base64编码字符串的代码转换为线程化任务以减少瓶颈。c#在setter中的线程

这是工作的代码:

private string _logoBase64; 
    public string logoBase64 
    { 
     get { return _logoBase64; } 
     set 
     { 
      _logoBase64 = value; 
      setLogo(); 
     } 
    } 
    public ImageSource logo { get; set; } 
      private void setLogo() 
    { 
     if ((this.logoBase64 != null) && (this.logoBase64.Length > 0)) 
     { 
      string _logoBase64 = this.logoBase64 
       .Replace("data:image/png;base64,", "") 
       .Replace("data:image/gif;base64,", "") 
       .Replace("data:image/jpeg;base64,", ""); 
      var image = new BitmapImage(); 
      try 
      { 
       image.BeginInit(); 
       image.StreamSource = new MemoryStream(Convert.FromBase64String(_logoBase64)); 
       image.EndInit(); 
       this.logo = image; 
      } 
      catch (Exception e) 
      { 
       Program.Errors.Add(e.Message + "\n" + e.StackTrace); 
       if (Program.environment == "development") 
       { 
        Console.WriteLine(e.Message); 
       } 
      } 
     } 
    } 

使用this例如,我试图将其转换为一个线程任务:

internal Task setLogoASync(string b64, CancellationToken cancellationToken) 
    { 
     return Task.Run(() => 
     { 
      var image = new BitmapImage(); 
      if ((b64 != null) && (b64.Length > 0)) 
      { 
       b64 = b64 
        .Replace("data:image/png;base64,", "") 
        .Replace("data:image/gif;base64,", "") 
        .Replace("data:image/jpeg;base64,", ""); 

       try 
       { 
        image.BeginInit(); 
        image.StreamSource = new MemoryStream(Convert.FromBase64String(b64)); 
        image.EndInit(); 
        this.logo = image; 
       } 
       catch (Exception e) 
       { 
        Program.Errors.Add(e.Message + "\n" + e.StackTrace); 
        if (Program.environment == "development") 
        { 
         Console.WriteLine(e.Message); 
        } 
       } 
      } 
      this.logo = image; 
     }, cancellationToken); 
    } 

但问题是二传手必须是异步,但它不可能。有没有解决的办法?

+11

的制定者通常的建议是,他们应该只用于非常短的运行操作之前。最好是完全删除它,只是提供一个公共方法 – thumbmunkeys

+1

你可以在setter中使用线程或BackgroundWorker,并让setter继续而不停止你的GUI –

+0

Saad Mind告诉我到底如何? – pgee70

回答

2

对setter的一般建议是,它们只能用于非常短的运行操作。

最好将其完全删除,而只是提供一个公共方法。

原因是作为一名程序员,我不应该考虑调用setter的意外影响和副作用。

让setter创建一个线程就计算时间和所用资源(例如CPU和内存)而言是一种意想不到的暗示。

2

每次修改图像时,都不要试图计算Base64实现,而是使用Lazy<T>在第一次实际请求时计算它。

private Lazy<ImageSource > _image; 
public ImageSource logo 
{ 
    get { return _image.Value; } 
} 

private string _logoBase64; 
public string logoBase64 
{ 
    get { return _logoBase64; } 
    set 
    { 
     _logoBase64 = value; 
     //Can't reset a Lazy, so we create a new one. 
     _image=new Lazy<ImageSource>(()=>imageFromBase64())); 
    } 
} 

//Initialize the Lazy in the constructor 
public MyClass() 
{ 
    _image=new Lazy<ImageSource>(()=>imageFromBase64())l 
} 

ImageSource imageFromBase64() 
{ 
    var image = new BitmapImage(); 
    if ((b64 != null) && (b64.Length > 0)) 
    { 
      b64 = b64 
       .Replace("data:image/png;base64,", "") 
       .Replace("data:image/gif;base64,", "") 
       .Replace("data:image/jpeg;base64,", ""); 

      try 
      { 
       image.BeginInit(); 
       image.StreamSource = new MemoryStream(Convert.FromBase64String(b64)); 
       image.EndInit(); 
      } 
      catch (Exception e) 
      { 
       Program.Errors.Add(e.Message + "\n" + e.StackTrace); 
       if (Program.environment == "development") 
       { 
        Console.WriteLine(e.Message); 
       } 
      } 
    } 
    return image; 
} 

为了避免延误即使是第logo请求时,你可以在一个一次性的任务发起慵懒的评价。懒惰保证其内容的并发访问,因此并不重要任务是否完成或不会有人请求标志

public string logoBase64 
{ 
    get { return _logoBase64; } 
    set 
    { 
     _logoBase64 = value; 
     //Can't reset a Lazy, so we create a new one. 
     var newLazy=new Lazy<ImageSource>(()=>imageFromBase64())); 
     //Start throwaway task before assigning to backing field, 
     //to avoid race conditions 
     Task.Run(()=>newLazy.Value); 
     _image=newLazy; 
    } 
} 
+0

这是一个好主意,但提供的代码不起作用,我看不到如何解决它。 private Lazy _image = new Lazy (()=> imageFromBase64()); =一个字段初始值设定项不能引用非静态字段,方法或属性'User.ImageFromBae64() – pgee70

+0

在你的构造函数中初始化它。 –

+0

谢谢你做到了。 – pgee70