【问题标题】:Silverlight: Threads / Delayed Actions / Asynchronous invocations/eventsSilverlight:线程/延迟操作/异步调用/事件
【发布时间】:2009-02-26 13:38:09
【问题描述】:

我有以下场景:当用户将鼠标移出弹出窗口时,我希望发生动画,五秒钟后,我想删除弹出窗口。

这是我希望使用的代码:

private bool leftPopup = false;
public void AnimatePopupOut(object sender, MouseEventArgs e)
{
   myAnim.Begin();
   (new Thread(new ThreadStart(delayedRemovePopup))).Start();
}

private void delayedRemovePopup()
{
   leftPopup = true;
   Thread.Sleep(5000);
   PopUp.IsOpen = false;
}

第一行“leftPopup = true”很好,但第三行“PopUp.IsOpen = false”给了我一个访问冲突异常,可能是因为这个对象属于GUI线程。有什么方法可以访问 PopUp.IsOpen 属性?如果没有,是否有另一种方法可以在一段时间后调用事件来执行此操作?

干杯

尼克

【问题讨论】:

    标签: silverlight multithreading events asynchronous


    【解决方案1】:

    尝试使用 PopUp.Dispatcher.Invoke()。这会将您的调用编组回 UI 线程。

    【讨论】:

    • 非常感谢您的建议。我使用“Action a = new Action(delayedRemovePopup); PopUp.Dispatcher.BeginInvoke(a);”代替了线程子句这解决了这一切。 :-) 非常感谢!
    • 仅供参考,您不需要临时变量,只需调用 Popup.Dispatcher.BeginInvoke(delayedRemovePopup);
    【解决方案2】:

    这是我在 WPF 中做的一个技巧。它被移植以在 Silverlight 中使用并挂起 Dispacher 类。我不知道莫里斯的回答,因为我在 SL5 中没有看到“调用”方法。我确实看到了 BeginInvoke,它在延迟操作方面毫无用处。

    用法:您必须在代码文件中包含 System.Windows 命名空间,否则此扩展方法将不会出现。

    // lets say you want to enable a control 1 second after a save event
    // lets say you just want to prevent click happy users from going crazy
    //   This code assumes you disabled the button on the click event
    Button b = this.idButton1;
    b.Dispatcher.DelayInvoke(TimeSpan.FromSeconds(1), () => { b.Enabled = true; });
    

    就是这样。只需一行代码就可以解决问题。下面是使上述代码成为可能的扩展类。

    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Threading;
    
    namespace System.Windows {
    
        public static class DispatcherExtensions {
    
            public static void DelayInvoke<TArg1, TArg2, TArg3>(this Dispatcher dispatcher, TimeSpan delay, Action<TArg1, TArg2, TArg3> action, TArg1 arg1, TArg2 arg2, TArg3 arg3) {
                dispatcher.DelayInvoke(delay, (Delegate)action, arg1, arg2, arg3);
            }
    
            public static void DelayInvoke<TArg1, TArg2>(this Dispatcher dispatcher, TimeSpan delay, Action<TArg1, TArg2> action, TArg1 arg1, TArg2 arg2) {
                dispatcher.DelayInvoke(delay, (Delegate)action, arg1, arg2);
            }
    
            public static void DelayInvoke<TArg1>(this Dispatcher dispatcher, TimeSpan delay, Action<TArg1> action, TArg1 arg1) {
                dispatcher.DelayInvoke(delay, (Delegate)action, arg1);
            }
    
            public static void DelayInvoke(this Dispatcher dispatcher, TimeSpan delay, Action action) {
                dispatcher.DelayInvoke(delay, (Delegate)action);
            }
    
            public static void DelayInvoke(this Dispatcher dispatcher, TimeSpan delay, Delegate del, params object[] args) {
    
                if (dispatcher == null)
                    throw new NullReferenceException();
                if (delay < TimeSpan.Zero)
                    throw new ArgumentOutOfRangeException("delay");
                if (del == null)
                    throw new ArgumentNullException("del");
    
                var task = new Task(() => { Thread.Sleep(delay); });
    
                task.ContinueWith((t) => { dispatcher.BeginInvoke(del, args); });
                task.Start();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 2019-01-15
      • 1970-01-01
      • 2016-09-03
      • 1970-01-01
      • 2016-06-08
      • 1970-01-01
      相关资源
      最近更新 更多