我的应用程序有一个简单的功能,它可以连接到Excel并在它们之间执行拖放操作。具体来说,我只是从我的应用程序中取一些文本值,将它们拖到Excel中,然后删除它们。
这种方法有90%的时间可以使用,但奇怪的是在某些时候,我的应用程序只是冻结了。我附加调试器并暂停执行,它被卡在DragDrop.DoDragDrop
- 这个函数永远不会返回,我的应用程序将永远挂起。
有没有办法确保DoDragDrop
可以返回?还是某种超时?这种情况只有在我将数据放入Excel时才会发生,因此据我所知,丢弃正在完成,函数应该在我的应用程序中返回。
这是我使用的代码:
DragDrop.DoDragDrop(sender as DependencyObject, draggable.GetDragDropString(), DragDropEffects.Copy);
GetDragDropString()
只是一个函数,它返回要在Excel中删除的数据字符串。
sender
只是我正在拖动的UI组件。像网格,编辑框,文本框等。可以是任何一个。
感谢您的帮助!
编辑:由于DragDrop.DoDragDrop
在某些情况下返回存在问题,或许有人可以帮助编写正确的超时?我已经尝试启动一个新的Thread
并使其超时,这在简单的情况下工作,并且当线程中的工作不需要UI资源时。但是,当我在一个带有超时的新线程中调用DoDragDrop
时,它会抛出一个异常,说线程无法访问该对象,因为另一个线程拥有它。所以我需要在同一个线程中调用这个函数。因此,当此函数在一定时间内无法返回时,我需要在UI线程上超时。
答案 0 :(得分:1)
我认为以下应该可以完成这项工作,但我会在进行时将其分解
public class DragDropTimer
{
private delegate void DoDragDropDelegate();
private System.Timers.Timer dragTimer;
private readonly int interval = 3000;
public DragDropTimer()
{
dragTimer = new System.Timers.Timer();
dragTimer.Interval = interval;
dragTimer.Elapsed += new ElapsedEventHandler(DragDropTimerElapsed);
dragTimer.Enabled = false;
dragTimer.AutoReset = false;
}
void DragDropTimerElapsed(object sender, ElapsedEventArgs e)
{
Initiate();
}
public void Initiate()
{
// Stops UI from freezing, call action async.
DoDragDropDelegate doDragDrop = new DoDragDropDelegate(DragDropAction);
// No async callback or object required
doDragDrop.BeginInvoke(null, null);
}
private void DragDropAction()
{
dragTimer.Enabled = false;
// Do your work here. or do work before and disable your timer upto you.
}
}
所以我们有一个基本的课程DragDropTimer
。我们在构造函数上设置了我们想要的间隔,如果您愿意,可能需要更改它,我们会在计时器上调用DragDropTimerElapsed
。
Initiate
是启动拖动所需的功能,它创建一个简单的委托,我们要求它执行DragAction
步骤,这是您完成所有工作并且计时器被禁用的地方。您可以选择仅在DragDrop成功时禁用计时器。如果计时器过去,我们再次拨打Initiate
以重新开始。
答案 1 :(得分:0)
另一个选择是以下列方式执行单独线程中的drop
Task.Factory.StartNew( () => { ... } );