I'm workin on a multi-thread application and I face the issue of having to use the clipboard (I'm working with the Qlikview API - and I need to copy tables into excel) and the problem is that I think what will happen is something like this: On thread#1 I open the QW document and copy the table, and before I get to paste it in the excel sheet, thread#2 comes along and uses the clipboard to copy table from its document. I'm curious whether it is even possible to use the clipboard from a multithreading application? I've read all sorts of things about using the clipboard and the only clear thing that I understood about it is that the method must be STA (?). So I'm kind of confused right now. Thank you
问题:
回答1:
Since the clipboard is a shared resource, you need to be very careful. It is indeed very likely that the operation in thread1 will be preempted by thread2. You should be able to use critical sections to get around that, but... you need to consider that other applications on the system are also involved, in ways that are hard to predict. Other clipboard listeners will be doing their thing, possibly pasting the data into themselves, or opening the clipboard to "peek" at the contents. This will foil your attempts to quickly copy/paste data, as you will probably need to wait 1000ms or so, after copying, before you can reliably paste it. You need to consider what's going to happen if the user has a clipboard extender running (you will be filling it up with your crap). How about remote desktop? You will have to wait for the clipboard sync across the network, which in some cases, means that you could have yet another set of clipboard monitoring applications eager to examine your clipboard data, before you get a chance to paste it.
Then consider the fact that the clipboard is intended for the user's convenience, not as a crutch for the programmer.
If you continue along this path, you are surely doomed. It's a bad idea, and impossible to implement without causing collateral damage. You should re-think your design. And no, I do not have any better ideas.
回答2:
Well, with multithreading, you can lock parts of the code that only one thread can run simultaneously. This is generally done to get a lock on resources that cannot be accessed simultaneously (like your clipboard example).
You define the following (in this example private
, so it would be in the class where you want to put your lock):
private readonly System.Object MyLock = new System.Object();
And then use
lock (MyLock)
{
// Locked Code
}
Now, no more than one thread can run the code inside the lock.
Note: in your case, this might still give problems if other applications/users start using the clipboard. If possible, you might want to consider using something different than the clipboard.
MSDN Thread Synchronization
回答3:
I had been facing the same issue some days ago when working on an specific automation. I was able to overcome this by blocking the processes while using the ClipBoard object, thus if the first thread needs to use the ClipBoard the others will need to wait for the process to finish. This way we can guarantee that we won't get wrong behavior during the paste of data in somewhere, since there will be no conflict on this resource.
So, my approach was to create a control variable in the environment (Environment.SetEnvironmentVariable) named "CLIPBOARD_INUSE" and set it to true
when an specific thread needs to perform ClipBoard methods. In the other threads, an while loop checks whether the variable "CLIPBOARD_INUSE" is false (resource is available) (make use of Thread.Sleep()
before checking again). When the first thread finishes using the ClipBoard it's time to release the resource by setting the control variable we created back to false
, so the next thread needing the ClipBoard can use it.
Hope you find this solution helpful as I did.
Regards,
Bruno Costa.