DoDragDrop иногда зависает приложение WinForms

Я делаю перетаскивание во внешнее приложение следующим образом:

string[] files = new string[/* */];

// get files

DataObject o = new DataObject(DataFormats.FileDrop, files);
DoDragDrop(o, DragDropEffects.Copy | DragDropEffects.Move);

и некоторые приложения возьмут файлы и перейдут к их обработке, и мое приложение может делать это бесплатно, но некоторые приложения заставят мое приложение зависать, пока оно не обработает все файлы ... есть ли способ обойти это? Я пытался сделать это в потоке, но это не сработало - это вообще не сработало ... итак, какие-либо предложения, как сделать так, чтобы этот код не зависал в моем приложении?


person argh    schedule 28.01.2010    source источник


Ответы (2)


.NET Control.DoDragDrop - это просто оболочка вокруг Win32 api под названием .. (подождите) .. DoDragDrop

Так что у него те же ограничения. DoDragDrop может быть вызван только из потока, который вызвал OleInitialize, что делает поток потоком типа STA (однопоточная квартира).

Поскольку он может использоваться только потоком STA, а разработка API является синхронной, вы зависите от обработки уведомлений об отбрасывании конечными приложениями. Это всего лишь часть дизайна OLE Drag and Drop, и его нельзя изменить. (OLE Drag and drop был фактически разработан в Windows 3x дней, до того, как потоки даже существовали в приложениях Windows).

Итак, вы могли бы возможно выполнить эту работу в другом потоке IFF, этот поток является потоком STA. Вам также, вероятно, придется использовать взаимодействие для вызова неуправляемой функции DoDragDrop.

person John Knoeller    schedule 29.01.2010
comment
Хм, это интересно, и я уверен, что вы правы, но это не решает проблему;) Я имею в виду ... Мне не нужно запускать DoDragDrop async ... все, что мне нужно сделать, это получить часть обмен данными на асинхронный ... Я где-то читал, что DataObject должен был бы реализовать какой-то асинхронный интерфейс, но я не могу его сейчас найти ... Вы, может быть, знаете, где я могу найти 'место', где мое приложение обменивается данные в другом приложении? (с использованием DoDragDrop ofc) - person argh; 30.01.2010
comment
Часть обмена данными находится внутри DoDragDrop, поэтому, если вы хотите, чтобы обмен данными был асинхронным, вам нужно поместить DoDragDrop в другой поток. и это должен быть поток STA. Вы знаете, как заставить поток быть STA в .NET? - person John Knoeller; 30.01.2010
comment
Что ж ... поправьте меня, если я ошибаюсь, но если у меня есть: [STAThread] static void Main (string [] parameters), то он запускается в потоке STA, верно? - person argh; 31.01.2010
comment
Устали от этого ... не повезло :( (возможно, я сделал что-то не так). А нет другого пути? Я читал что-то о DataObject, реализующем некоторый интерфейс asnyc? - person argh; 23.02.2010
comment
@argh: извините, я ничего об этом не знаю. Раймонд Чен написал о реализации перетаскивания в своем блоге, вы можете попробовать посмотреть на него (хотя C ++, а не C #) blogs .msdn.com / oldnewthing - person John Knoeller; 23.02.2010

Он всегда будет зависать, но для небольших файлов задержка не заметна. Ознакомьтесь с этим ответом.

person bohdan_trotsenko    schedule 15.09.2010