当我的应用程序出现大问题时,我正在尝试实现游标更改。 我正在尝试这个
public class CursorWait : IDisposable
{
public CursorWait(bool appStarting = false, bool applicationCursor = false)
{
// Wait
Cursor.Current = appStarting ? Cursors.AppStarting : Cursors.WaitCursor;
if (applicationCursor) Application.UseWaitCursor = true;
}
public void Dispose()
{
// Reset
Cursor.Current = Cursors.Default;
Application.UseWaitCursor = false;
}
}
还有这个
public static class UiServices
{
private static bool IsBusy;
public static void SetBusyState()
{
SetBusyState(true);
}
private static void SetBusyState(bool busy)
{
if (busy != IsBusy)
{
IsBusy = busy;
Mouse.OverrideCursor = busy ? Cursors.Wait : null;
if (IsBusy)
{
new DispatcherTimer(TimeSpan.FromSeconds(0), DispatcherPriority.ApplicationIdle, dispatcherTimer_Tick, Application.Current.Dispatcher);
}
}
}
private static void dispatcherTimer_Tick(object sender, EventArgs e)
{
var dispatcherTimer = sender as DispatcherTimer;
if (dispatcherTimer != null)
{
SetBusyState(false);
dispatcherTimer.Stop();
}
}
}
但两种情况都给我错误:调用线程必须是STA,因为许多UI组件都需要这个。
在我的应用程序中,我正在使用特殊调用来创建数据库和用户权限。 此代码如下所示:
Task.Run(() => TryExecute(securedAction)).ContinueWith(taskResult =>
{
var application = Application.Current;
if (DoneActionCanBeDone(doneAction, taskResult))
{
if (application != null)
{
application.Dispatcher.InvokeAsync(() => doneAction(taskResult.Result));
}
else
{
doneAction(taskResult.Result);
}
}
else if (taskResult.Status != TaskStatus.RanToCompletion)
{
if (application != null)
{
application.Dispatcher.InvokeAsync(
() => InvokeRollbackAction(rollbackAction, suppressError, taskResult));
}
else
{
InvokeRollbackAction(rollbackAction, suppressError, taskResult);
}
}
});
我的光标更改应在Task.Run之前开始,在结束之后结束。 谢谢你的建议。
答案 0 :(得分:1)
我将一些代码放在winforms应用程序中并从单击事件处理程序运行它。
private void button1_Click(object sender, EventArgs e)
{
var cw = new CursorWait(false, true);
这没问题。 这让我觉得如果你收到错误,你可能会从非ui线程中调用它。 将您的呼叫转移到ui线程上的某个位置。
除非您使用旧版本的.net,否则我建议您查看异步并等待任务,而不是使用所有可以继续使用的内容。
答案 1 :(得分:1)
这里有一个类似MVVM的方法,利用异步等待:
观点:
class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel ( )
{
DoMethod = new DelegateCommand ( Method );
}
public async void Method ( )
{
// Lets define our time consuming worker
string Worker ( )
{
Thread.Sleep ( 5000 );
return "result";
};
// This part executes in the main thread
IsBusy = true;
// The Scheduler will direct the main thread to execute something else while the task is not done
var result = await Task.Factory.StartNew ( Worker );
// Task is done, the rest will execute back in the main thread
IsBusy = false;
}
public ICommand DoMethod { get; private set; }
public bool IsBusy { get { return _isBusy; }
set { _isBusy = value; OnPropertyChanged ( ); } }
private bool _isBusy;
}
viewmodel:
Locale.current.localizedString(forRegionCode:)
// "NZ" -> "New Zealand"
即使你没有使用MVVM模式,async await结构在你的情况下应该仍然有效。
答案 2 :(得分:-1)
如果你的目标是在开始任务/漫长过程之前更改光标,然后完成任务/漫长过程更改光标恢复正常那么下面的代码可能会有所帮助。
如果以下代码符合您的情况,请告诉我。
private void LongProcess()
{
// Write your code/call method to change cursor
Cursor = Cursors.Wait;
Task.Factory.StartNew(() =>
{
// Write your code which do long process or
// call method which do the same
System.Threading.Thread.Sleep(10000);
}).ContinueWith(t =>
{
Dispatcher.Invoke(() =>
{
// Write your code/call method to change cursor back to normal
Cursor = Cursors.Arrow;
});
});
}