Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当另一个线程运行时,WPF动画停止_Wpf_Animation - Fatal编程技术网

当另一个线程运行时,WPF动画停止

当另一个线程运行时,WPF动画停止,wpf,animation,Wpf,Animation,我有一个窗口,当另一个线程正在运行时显示一个“正在工作”的动画。窗口显示,我可以看到进度条,但动画已冻结。代码在ViewModel上运行,并在构造函数中创建dispatcher: _dispatcher = Dispatcher.CurrentDispatcher; 创建动画并运行该过程的代码如下所示: Working wrk; protected void Search() { ImplementSearch(); wrk = new Working(); wrk.Ow

我有一个窗口,当另一个线程正在运行时显示一个“正在工作”的动画。窗口显示,我可以看到进度条,但动画已冻结。代码在ViewModel上运行,并在构造函数中创建dispatcher:

_dispatcher = Dispatcher.CurrentDispatcher;
创建动画并运行该过程的代码如下所示:

Working wrk;    
protected void Search()
{
  ImplementSearch();

  wrk = new Working();
  wrk.Owner = (MainWindow)App.Current.MainWindow;
  wrk.WindowStartupLocation = WindowStartupLocation.CenterOwner;
  wrk.HeadingMessage = "Searching...";
  wrk.UpdateMessage = "Running your search";
  wrk.ShowDialog();      
}

void ImplementSearch()
{
  System.Threading.Thread thread = new System.Threading.Thread(
    new System.Threading.ThreadStart(
      delegate()
      {
        System.Windows.Threading.DispatcherOperation
          dispatcherOp = _dispatcher.BeginInvoke(
          System.Windows.Threading.DispatcherPriority.Normal,
          new Action(
            delegate()
            {                  
              ResetSearch();

              string ret = _searchlogic.PerformSearch(SearchTerm, ref _matchingobjects, TypeOfFilter());
              if (ret != null)
                SearchMessage = ret;

              if (_matchingobjects.Count > 0)
              {
                DataRow row;
                foreach (SearchLogicMatchingObjects item in _matchingobjects)
                {
                  row = _dt.NewRow();
                  row["table"] = item.Table;
                  row["pk"] = item.PK;
                  _dt.Rows.Add(row);
                }

                SelectCurrent();
              }          
            }
        ));

        dispatcherOp.Completed += new EventHandler(dispatcherOp_Completed);
      }
  ));

  thread.Start();
}

void dispatcherOp_Completed(object sender, EventArgs e)
{
  wrk.Close();
}
我不明白为什么动画停止了?有人能帮忙吗?
谢谢

您的线程没有做任何有用的事情-通过使用
\u dispatcher.BeginInvoke
运行搜索,您可以在UI线程上有效地执行搜索,从而阻止动画。从后台线程使用dispatcher仅用于操作UI控件或引发PropertyChanged事件的操作。

我认为您希望在后台线程上执行实际工作,而不是将所有内容封送到UI线程,这正是BeginInvoke所做的!通过使用BeginInvoke在UI线程上执行所有操作,动画将无法运行

Working wrk;     
protected void Search() 
{ 
  ImplementSearch(); 

  wrk = new Working(); 
  wrk.Owner = (MainWindow)App.Current.MainWindow; 
  wrk.WindowStartupLocation = WindowStartupLocation.CenterOwner; 
  wrk.HeadingMessage = "Searching..."; 
  wrk.UpdateMessage = "Running your search"; 
  wrk.ShowDialog();       
} 

void ImplementSearch() 
{ 
    Thread thread = new Thread(new ThreadStart( 
      delegate() 
      { 
          // Call to function which changes UI - marshal to UI thread.
          _dispatcher.BeginInvoke((Action)(() => ResetSearch()));

          string ret = _searchlogic.PerformSearch(SearchTerm, ref _matchingobjects, TypeOfFilter()); 

          if (ret != null) 
          {
              // Call to function which changes UI - marshal to UI thread.
              _dispatcher.BeginInvoke((Action<string>)((r) => SearchMessage = r), ret);
          }

          if (_matchingobjects.Count > 0) 
          { 
            DataRow row; 
            foreach (SearchLogicMatchingObjects item in _matchingobjects) 
            { 
              row = _dt.NewRow(); 
              row["table"] = item.Table; 
              row["pk"] = item.PK; 
              _dt.Rows.Add(row); 
            }  

            // Call to function which changes UI - marshal to UI thread.
            _dispatcher.BeginInvoke((Action)(() => SelectCurrent()));
          }           
        } 

        wrk.Close();
  })); 
  thread.Start();
} 
workingwrk;
受保护的无效搜索()
{ 
实现搜索();
wrk=新加工();
wrk.Owner=(MainWindow)App.Current.MainWindow;
wrk.WindowStartupLocation=WindowStartupLocation.CenterOwner;
wrk.HeadingMessage=“搜索…”;
wrk.UpdateMessage=“运行您的搜索”;
wrk.ShowDialog();
} 
无效搜索()
{ 
线程=新线程(新线程开始(
代表()
{ 
//调用将UI-marshal更改为UI线程的函数。
_dispatcher.BeginInvoke((操作)(()=>ResetSearch());
string ret=_searchlogic.PerformSearch(SearchTerm,ref _matchingobjects,typeofilter());
如果(ret!=null)
{
//调用将UI-marshal更改为UI线程的函数。
_dispatcher.BeginInvoke((操作)((r)=>SearchMessage=r),ret);
}
如果(_matchingobjects.Count>0)
{ 
数据行;
foreach(在匹配对象中搜索逻辑匹配对象项)
{ 
行=_dt.NewRow();
行[“表”]=项.表;
行[“主键”]=item.pk;
_dt.行。添加(行);
}  
//调用将UI-marshal更改为UI线程的函数。
_dispatcher.BeginInvoke((操作)(()=>SelectCurrent());
}           
} 
wrk.Close();
})); 
thread.Start();
} 

干杯!我已经成功地实现了这一点,尽管它引发了其他相关问题。具体来说,当搜索返回多个匹配对象时,不会填充_matchingobjects列表。这个列表是在UI线程中声明的,所以我想这就是问题所在。我还必须使用这个ObservableCollectionEx来防止异常。我将继续学习我对线程的基本理解!删除关于列表未被填充的注释通常,您可以在任何线程上访问非UI对象,但是您需要注意,多个线程不会同时尝试读取/写入它们。此外,线程间的操作不保证以任何顺序进行,这对于线程新手来说通常是错误的来源。Ok。这也许解释了我奇怪的新问题。当我运行一个只返回一次命中的搜索并且不需要datatable(_dt)时,一切都正常。如果我运行一个返回多条记录的搜索,它第一次工作,但是当我再次运行相同的搜索时,我得到一个错误{“位置0处没有行。”}。如果我一步一步地看代码,它似乎在工作,但当正常运行时,我会得到错误。这就好像数据表没有及时填充一样。有什么建议吗?尝试锁定对任何共享状态的访问。如果需要多个读卡器,可以使用
lock
关键字(在封面下使用
System.Threading.Monitor
),或使用类似
System.Threading.ReaderWriterLockSlim
的内容。在这里可以看到一个关于同步的极好的视图:在该页面上向下滚动到“锁定和线程安全”并享受!但是,请注意,线程可能非常难以调试。如果您可以选择不共享状态,而是处理副本或返回值,这样会更好。