2011-12-14 60 views
1

我看了一下這個錯誤很多帖子,但我不知道它如何能在我的解決方案來解決((我有一個進度對話框,在IT-一些邏輯這是從大型機通過ButtonClick稱爲調用線程不能訪問該對象

void OnBtnClick(object sender, RoutedEventArgs e) 
{ 
    ProgressDialog dlg = new ProgressDialog(""); 
    dlg.Closing += new CancelEventHandler(dlg_Closing); 
    dlg.Closed += new EventHandler(dlg_Closed); 
    //dlg.AutoIncrementInterval = 0; 
    LibWrap lwrap = new LibWrap(); 
    DoWorkEventHandler handler = delegate 
    { 
     BitmapFrame bf = wrap.engine(BitmapFrame.Create(FXPhotoStudio.App 
                  .draggedImage), 
            this.fxPSEditorView); 
    }; 
    dlg.CurrentLibWrap = lwrap; 
    dlg.AutoIncrementInterval = 100; 
    dlg.IsCancellingEnabled = true; 
    dlg.Owner = Application.Current.MainWindow; 
    dlg.RunWorkerThread(0, handler); 
} 

也有此進度條的對話框

void dlg_Closed(object sender, EventArgs e) 
{ 
    try 
    { 
     mainFrameView.CurrentImage = effectedImage;//!error here! 
    } 
} 

的effectedImage是大型機的領域在封閉的情況下同一類(大型機)的處理程序。它由我的ProgressDialog設置。 我使ProgressDialog.cs如下:

(this.Owner as MainFrame).effectedImage = currentLibVrap.GetEffectedImage; 

currentLibVrapOnBtnClick設置 - 見上 誰能幫我解決這個問題?

這是關閉ProgressBarDialog代碼:

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if (!Dispatcher.CheckAccess()) 
     { 
     //run on UI thread 
     RunWorkerCompletedEventHandler handler = worker_RunWorkerCompleted; 
     Dispatcher.Invoke(DispatcherPriority.SystemIdle, handler, new object[] {sender, e}, null); 
     return; 
     } 

     if (e.Error != null) 
     { 
     error = e.Error; 
     } 
     else if (!e.Cancelled) 
     { 
     //assign result if there was neither exception nor cancel 

      (this.Owner as MainWindow).effectedImage = currentLibVrap.GetEffectedImage;//! ok there 

     result = e.Result; 
     } 

    //update UI in case closing the dialog takes a moment 
// progressTimer.Stop(); 
    progressBar.Value = progressBar.Maximum; 
    btnCancel.IsEnabled = false; 

    //set the dialog result, which closes the dialog 
    DialogResult = error == null && !e.Cancelled; 
} 

而且還有工作過程:

/// Launches a worker thread which is intended to perform 
/// work while progress is indicated, and displays the dialog 
/// modally in order to block the calling thread. 
/// </summary> 
/// <param name="argument">A custom object which will be 
/// submitted in the <see cref="DoWorkEventArgs.Argument"/> 
/// property <paramref name="workHandler"/> callback method.</param> 
/// <param name="workHandler">A callback method which is 
/// being invoked on a background thread in order to perform 
/// the work to be performed.</param> 


    public bool RunWorkerThread(object argument, DoWorkEventHandler workHandler) 
    { 
     if (autoIncrementInterval.HasValue) 
     { 
     //run timer to increment progress bar 
     progressTimer.Interval = TimeSpan.FromMilliseconds(autoIncrementInterval.Value); 
     progressTimer.Start(); 
     // LibWrap lwrap = new LibWrap(); 
     // BitmapFrame bf = lwrap.engine(BitmapFrame.Create(FXPhotoStudio.App.draggedImage));//(aa.Image); 

     } 

     //store the UI culture 
     uiCulture = CultureInfo.CurrentUICulture; 

     //store reference to callback handler and launch worker thread 
     workerCallback = workHandler; 
     worker.RunWorkerAsync(argument); 

     //display modal dialog (blocks caller) 
     return ShowDialog() ?? false; 
    } 

/// <summary> 
/// Worker method that gets called from a worker thread. 
/// Synchronously calls event listeners that may handle 
/// the work load. 
/// </summary> 
private void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
    //make sure the UI culture is properly set on the worker thread 
    Thread.CurrentThread.CurrentUICulture = uiCulture; 
    //invoke the callback method with the designated argument 
    workerCallback(sender, e); 
    } 
    catch (Exception) 
    { 
    //disable cancelling and rethrow the exception 
    //Dispatcher.BeginInvoke(DispatcherPriority.Normal, 
    //      (SendOrPostCallback) delegate { btnCancel.SetValue(Button.IsEnabledProperty, false); }, 
    //      null); 
    return; 
    //throw; 
    } 
} 
+1

你需要調用`Invoke()`來在你的UI線程中調用一個函數。 – ThePower 2011-12-14 09:32:49

回答

1

您可以使用Dispather.Invoke或Dispatcher.BeginInvoke。它們都會調用UI線程的調用(這就是你的錯誤所在),BeginInvoke是爲在後臺線程中運行繁重的操作而設計的,而Invoke只是一個編組器,所以對於你的類型任務,我會堅持最後一個一。

這裏是你如何做到這一點(假設mainFrameView.CurrentImageImage型的,否則只是改變中不管它是什麼):

C#

更新1使用的參數,以避免一個唯一的名稱與現有的變量名稱保持一致。

mainFrameView.Dispatcher.Invoke(new Action<object>((myImage2012) => 
{ mainFrameView.CurrentImage = (Image)myImage2012; }), 
new object[1] { effectedImage }); 
1

你需要使用Dispatcher.BeginInvoke做調度它UI線程(調度和立刻返回)或Dispatcher.Invoke (阻塞,直到行動派遣)

這是因爲,在默認情況下,線程模型的應用程序是單threa代客公寓(STA)。這意味着,僅螺紋,其創建的UI元素,能夠與它進行交互,其他線程,它想做的事與UI元素的東西,必須調度對元素UI線程他們的行動

void dlg_Closed(object sender, EventArgs e) 
{ 
    try 
    { 
     mainFrameView.CurrentImage = effectedImage;//!error here! 
    } 
} 

確定UI線程發送此事件?你有沒有嘗試調度設置CurrentImage? 你能不能請簡化你的代碼,只留下相關的方法?

UPD:我的意思是,你試圖派遣CurrentImage設置?

Application.Current.MainWindow.Dispatcher.BeginInvoke(new Action(()=> 
              { 
               mainFrameView.CurrentImage = effectedImage; 
              })); 
+0

您是否嘗試過我的示例代碼?它是否適合您? – 2011-12-14 10:14:51

+0

我已經嘗試調度CurrentImage設置,因爲你寫但它落在mainFrameView。具有相同錯誤的CurrentImage(( – 2011-12-14 11:01:26

相關問題