2011-12-14 64 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

相关问题