当前位置: 代码迷 >> C# >> 小女子请问线程里剪切板取值有关问题
  详细解决方案

小女子请问线程里剪切板取值有关问题

热度:448   发布时间:2016-05-05 05:19:32.0
小女子请教线程里剪切板取值问题。
这里模拟了个按键Ctrl+C的操作。代码省略。
如果按正常流程string sclip = Clipboard.GetText(); 可以取到值。
按照以下加了个Timer的方式就取到的值是空。
这是为什么那。应该如何修改那。

在主线程里可以取到值。在线程里取不到值。估计还是线程同步的问题。

请各位前辈赐教!代码如下:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;

namespace TimerTest
{
    public partial class Form1 : Form
    {

        // 代理实现异步调用以设置TextBox控件text属性
        delegate void SetTextCallback(string text);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
         //这里模拟了个按键Ctrl+C的操作。代码省略。
         //如果按正常流程string sclip = Clipboard.GetText(); 可以取到值。
         //按照以下加了个Timer的方式就取到的值是空。
         //这是为什么那。

            System.Timers.Timer aTimer = new System.Timers.Timer();
            aTimer.Elapsed += new ElapsedEventHandler(TimeEvent);
            // 设置引发时间的时间间隔 此处设置为1秒(1000毫秒)
            aTimer.Interval = 5000;
            aTimer.Enabled = true;
        }

         // 当时间发生的时候需要进行的逻辑处理等
            //  在这里仅仅是一种方式,可以实现这样的方式很多.
        private void TimeEvent(object source, ElapsedEventArgs e)
       {
           string sclip = Clipboard.GetText();
           //这里为什么取到的sclip的值是空。
           //但是我把Clipboard.GetText(); 放到Form1_Load或者button1_Click里都能
           //取到值。这里加了一个Timer就取不到值了。
            label1.Text = sclip;
  
       }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
        
    }
}

------解决思路----------------------
msdn文档里有写,Clipboard只能在STA模式的线程使用,timer使用的线程池线程不是STA的,所以不对。或者同步到UI线程调用,或者自己建立线程,使用其SetApartmentState方法设置成STA模式再启动。
------解决思路----------------------
如果是QQ聊天的图文混排可以这样设置

http://bbs.csdn.net/topics/390854635
------解决思路----------------------
现在,基本上每一个人都知道在子线程中要写
private void TimeEvent(object source, ElapsedEventArgs e)
{
       this.BeginInvoke((Action)delegate    //或者 this.Invoke(...)
        {
             .....
        });
}

这样的代码的。
------解决思路----------------------
如果使用 Timers.Timer,你或者用鼠标把它拖入界面(这会自动设置SynchronizingObject 属性),或者(如果用代码创建的话)就要手动设置SynchronizingObject 属性
    System.Timers.Timer aTimer = new System.Timers.Timer();
    aTimer.SynchronizingObject = this;
    aTimer.Elapsed += new ElapsedEventHandler(TimeEvent);
    // 设置引发时间的时间间隔 此处设置为1秒(1000毫秒)
    aTimer.Interval = 5000;
    aTimer.Enabled = true;


引用:
那我试一下Forms.Timer

你应该了解一下为什么可以用 Forms.Timer。
  相关解决方案