2017-07-07 42 views
1

所以我必須更新程序使用Awesomium較新版本的形式,特別是1.7.5與更新Awesomium現在有它自己的線程操作創建訂閱了事件從阻塞線程

好,而且它阻塞了。

我可以使用WebCore.QueueWork()將工作排隊到阻塞線程,這將完成在線程WebCore.Run()被調用時傳遞的操作。我一定要給它自己的線程,這樣我的應用程序的其餘部分就不會被阻塞。

程序用於執行功能的方式是創建一個具有構造函數的工作對象,該構造函數使用WebCore庫實例化WebView和WebSession。然後它創建一個接受工作對象作爲參數的表單,該表單允許表單訂閱來自WebCore庫的事件。

var worker = new Worker(); 
var debugForm = new PBForm(worker); 
debugForm.Show(); 

工作人員構造函數有這行代碼,每當視圖更新時調用函數SurfaceIsDirty。

((ImageSurface)_view.Surface).Updated += (s, e) => { if (webView_SurfaceIsDirty != null) webView_SurfaceIsDirty(s, e); }; 

此功能分配的形式構造:

this.worker.webView_SurfaceIsDirty = (sender, e) => 
{ 
    ImageSurface buffer = (ImageSurface)this.worker._view.Surface; 
    pictureBox1.Image = buffer.Image; 
}; 

所以格式的圖片更新每當WebView中被更新。

這用於能夠在WebCore線程中運行,但現在自從WebCore線程被阻塞後,我無法讓此表單正常工作。

所以這就是我卡住的地方。我需要在一個單獨的線程中運行表單,因此它不會掛起,因爲它阻塞了WebCore線程。

我的想法是:

  1. 當工人創造了一個新的線程爲工人實例的屬性創建表單。
  2. 當發生WebCore事件時,工作者實例應該能夠更新它的Form。

它的編譯,表單是響應,但圖片沒有更新,我懷疑它是與現在在不同線程中的窗體有關。下面是相關的代碼,我現在所擁有的:

我添加了這個屬性工人階級:

public PBForm2 DebugForm; 

我實例在WebCore的阻塞線程工人階級:

WebCore.QueueWork(AddWorker); 

在AddWorker方法我做一個新的線程並運行一個窗體,同時將其附加到工人屬性:

static void AddWorker() 
{ 
    var worker = new Worker(); 
    Workers.Add(worker); 
    new Thread(() => 
    { 
     worker.DebugForm = new PBForm2(worker.Id); 
     var debugForm = new PBForm2(worker.Id); 

     Application.Run(debugForm); 
     Application.DoEvents(); 

    }).Start(); 
} 

最後工人事件本身目前是:

((ImageSurface)_view.Surface).Updated += (s, e) => 
{ 
    ImageSurface buffer = (ImageSurface)_view.Surface; 
    DebugForm.pictureBox1.Image = buffer.Image; 
    DebugForm.pictureBox1.Refresh(); 
}; 

似乎非常接近的工作,形式響應用戶交互和工作人員都在做自己的事情,並觸發事件,但是畫面沒有在改變形成。事件正在發生,新的圖像在那裏,我懷疑窗體是在不同的線程中導致窗體上的圖像不能更新。

這是一篇很長的文章,所以如果你正在閱讀這篇文章,感謝你花時間來完成這一切。當談到線程和任何建議或鏈接時,我是一個非常新手,甚至不知道爲了解決這個問題搜索什麼,將不勝感激。

回答

1

我想通了,固定在那裏我被更新錯誤的Form對象(感謝特洛伊Mac1ure)我遇到了一個線程問題,我無法訪問的問題後來自Awesomium線程的表單的圖片框。

我解決它使用一個輔助類:

public static class ThreadHelper 
{ 
    private delegate void SetPictureCallback(PBForm f, Image image); 
    private delegate void AppendTextCallback(PBForm f, string text); 

    public static void SetPicture(PBForm form, Image image) 
    { 
     if (form.InvokeRequired) 
     { 
      SetPictureCallback d = SetPicture; 
      form.Invoke(d, form, image); 
     } 
     else 
     { 
      form.pictureBox1.Image = image; 
      form.pictureBox1.Refresh(); 
     } 
    } 

    public static void AppendText(PBForm form, string text) 
    { 
     if (form.InvokeRequired) 
     { 
      AppendTextCallback d = AppendText; 
      form.Invoke(d, form, text); 
     } 
     else 
     { 
      form.textBox1.Text += text; 
      form.textBox1.SelectionStart = form.textBox1.TextLength - 1; 
      form.textBox1.ScrollToCaret(); 
      form.textBox1.ScrollToCaret(); 
     } 
    } 
} 

當事件發生時的工作線程我調用該函數更新表單觸發:

_view.Surface = new ImageSurface(); 
((ImageSurface)_view.Surface).Updated += (s, e) => 
{ 
    ImageSurface buffer = (ImageSurface)_view.Surface; 
    ThreadHelper.SetPicture(DebugForm, buffer.Image); 
    Application.DoEvents(); 
}; 

_view.ConsoleMessage += (s, e) => 
    ThreadHelper.AppendText(DebugForm, string.Format("{0} : {1} [{2}]\r\n", e.LineNumber, e.Message, e.Source)); 
2

您正在創建的相同形式2:

worker.DebugForm = new PBForm2(worker.Id); 
var debugForm = new PBForm2(worker.Id); 

然後加載debugForm,但您的更新正在做DebugForm.picturebox1所以您的更新將不可見。更新將需要完成debugForm.picturebox1,但你應該只有一個創建。

沒有看到所有的代碼,爲什麼不只是加載一個工人類或指向另一個?

Application.Run(worker.DebugForm); 
Application.DoEvents(); 

worker.DebugForm = new PBForm2(worker.Id); 
var debugForm = worker.DebugForm; 

Application.Run(debugForm); 
Application.DoEvents(); 
+0

那麼這個固定的一個問題,但導致到另一個,我不能從Awesomium線程觸發該事件的窗體的pictureBox1。我通過創建一個靜態類來調用Form.Invoke函數正確調用窗體的更改。 –