별도의 스레드에서 생성해야하는 작업을 사용하고 있음에도 불구하고 응용 프로그램에서 UI 프로세스가 멈추는 문제가 있습니다.UI 스레드가 잠기는 것을 어떻게 중지합니까?
<Image Name="LoadingCog" Source="/Resources/Cog.png" Margin="0,37" Width="60" Height="60" HorizontalAlignment="Center" RenderTransformOrigin="0.5,0.5">
<Image.Resources>
<Storyboard x:Key="LoadingCogRotateStoryboard">
<DoubleAnimation
Storyboard.TargetName="LoadingCogRotateTransform"
Storyboard.TargetProperty="Angle"
By="10"
To="360"
Duration="0:0:7"
FillBehavior="Stop"
RepeatBehavior="Forever" />
</Storyboard>
</Image.Resources>
<Image.RenderTransform>
<RotateTransform x:Name="LoadingCogRotateTransform" Angle="0" />
</Image.RenderTransform>
</Image>
가 나는 또한 내에서 이벤트 처리기가 코드 숨김에 대한 :
나는 여기에 XAML은, 내가/같이 필요에 따라 숨겨진되고있는 로딩 창에서 회전하고 이미지가 윈도우의 가시성이 변경 될 때 애니메이션을 다시 시작하는 창
void LoadingScreenWindow_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var storyBoard = (System.Windows.Media.Animation.Storyboard)LoadingCog.Resources["LoadingCogRotateStoryboard"];
if (IsVisible == true)
{
storyBoard.Seek(TimeSpan.Zero);
storyBoard.Begin();
}
else
{
storyBoard.Stop();
}
}
나는/숨어/다음과 같은 방법이있다 로딩 창에서 메시지를 변화 보여주는 담당하는 컨트롤러가 있습니다
를Task.Factory.StartNew(() =>
{
LoadingScreenController.ShowLoadingScreen("Loading application, please wait..");
PerformNotSoIntensiveLoadingOperation();
HideLoadingScreen();
System.Windows.Application.Current.Dispatcher.Invoke((Action)(() =>
{
LoginWindow.Show();
}));
LoadingScreenController.ShowLoadingScreen("Logging in, please wait..");
PerformIntensiveLoadingOperations();
LoadingScreenController.HideLoadingScreen();
System.Windows.Application.Current.Dispatcher.Invoke((Action)(() =>
{
MainWindow.Show();
}));
}, TaskCreationOptions.LongRunning);
내가 실제로 새 스레드를 얻을 수 있도록하기 위해 TaskCreationOptions.LongRunning
를 사용하여 내 App.xaml.cs
파일에서
internal void ShowLoadingScreen(string loadingMessage)
{
Application.Current.Dispatcher.Invoke((Action)(() =>
{
_viewModel.LoadingMessage = loadingMessage;
_loadingWindow.Show();
}));
}
internal void HideLoadingScreen()
{
Application.Current.Dispatcher.Invoke((Action)(() =>
{
_loadingWindow.Hide();
}));
}
는
내 응용 프로그램의로드 프로세스를 시작하려면 다음과 유사한 코드가 있습니다.
PerformNotSoIntensiveLoadingOperation()
의 코드가 내 PC에서 실행되는 데 그리 오래 걸리지 않으므로 로딩 애니메이션이 제대로 작동합니다.
창을 숨기고보다 집중적 인 작업을 PerformIntensiveLoadingOperations()
에서 실행하면 다시 창이 나타나 애니메이션이 멈 춥니 다.
집중적 인 작업이 완료된 후에 창이 열리면 예상대로 애니메이션이 계속됩니다. 대한 명확한
, 프로세스는 다음과 같다 :
표시 로딩 화면>> 다른 창을 표시하는 창을 닫기 전에 사용자 상호 작용을 기다립니다> 몇 가지 작업> 숨기기 로딩 화면을> 다시 로딩 창을 보여> 어떤을 더 많은 작업> 윈도우 다시로드 숨기기> 메인 응용 프로그램 윈도우 보이기
Task
의 스레드 (UI 코드를 전혀 건드리지 않음)의 애니메이션이 멈 추면 그 부분은 do some more work
입니다.
.Net 4.0.3을 사용하고 있습니다.
Application.Current.Dispatcher.Invoke
으로 전화를 끊으면 호출 스레드가 액세스하려고하는 개체를 소유하고 있지 않다는 것을 알려주는 예상 크로스 스레드 위반 예외가 발생하므로 코드가 UI 스레드에서 실행되지 않습니다.
이 원인은 무엇이며 어떤 일이 발생하지 않도록 할 수 있습니까?
내 상황에서 수행되는 유일한 UI 작업은 창 표시/숨기기입니다. 그 후 모든 코드는 웹 서비스 및 데이터베이스 작업에 대한 호출을 처리합니다. 또한 Dispatcher를 명시 적으로 사용하여 show/hide 메서드 (예 : 내 코드 예제와 같이)를 호출하지 않고 (예상대로) "호출 스레드가이 개체를 소유하지 못했습니다."오류가 발생했습니다. 로딩 윈도우는 매우 간단합니다. 전체 텍스트가 표시되는'TextBlock'과'Image'가 있습니다. 로딩 윈도우가 숨겨진 후에 다른 윈도우가 표시됩니다. 애니메이션이 적용되지 않는 경우에는 상관 없습니다. – Sean
'이지만 응용 프로그램에서 UI의 데이터 렌더링을 시작하면 통화 중 표시기가 멈 춥니 다.' UI 스레드는 UI의 나머지 부분을 렌더링하는 동안 통화 중 표시기에 애니메이션을 적용 할 수 없습니다. – AwkwardCoder
@AwkwardCoder 어느 시간까지 로딩 창이 숨겨져 있으며 그것이 애니메이션이기 때문에 움직이지 않아도 상관 없어요. 어쨌든 숨겨졌다. 무슨 일이 일어나고 있는지, 로딩 화면을 보이고,로드 스크린을 숨기고, 다른 윈도우를 보여 주며, 사용자 상호 작용을 기다리고, 윈도우를 닫고, 로딩 윈도우를 보여주고, 더 많은 일을하고, 다시 숨기며, 메인 애플리케이션 창. 그것은 내 애니메이션이 멈추고있는 Task의 스레드 (어떤 UI 코드도 건드리지 않음)에서 "어떤 일을하고있는 중"과 "더 많은 일을하고있는"동안입니다. – Sean