【问题标题】:Method to Use a fifo Queue with background worker, and populating the queue with method(parameter)使用带有后台工作程序的 fifo 队列的方法,并使用方法(参数)填充队列
【发布时间】:2015-10-22 23:24:06
【问题描述】:

目前我正在尝试创建一个可以循环访问某些类函数的后台工作程序,我创建了一个类来存储一些全局使用的对象(用户设置和其他一些东西)。

我基本上需要将以下行存储为操作。

GV_Acc.load_page("weburl", 0);

这是我使用的大部分代码
包含按钮的表单:

private void btn_initialize_Click(object sender, EventArgs e){
    CusWorker worker = new CusWorker();
    worker.addwork(GV_Acc.load_page("weburl", 0));
    worker.addwork(GV_Acc.json_populate(0));
    worker.asyncworker.RunWorkerAsync();}

这是我正在使用的 2 个类:

public class CusWorker
{
    public BackgroundQueue asyncqueue { get;private set; }
    private int tasks;
    public System.ComponentModel.BackgroundWorker asyncworker = new System.ComponentModel.BackgroundWorker();
    public CusWorker()
    {
        asyncqueue = new BackgroundQueue();
        asyncworker.DoWork += new System.ComponentModel.DoWorkEventHandler(asyncworker_DoWork);
        asyncworker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(asyncworker_RunWorkerCompleted);
    }
    public void addwork(Action action)
    {
        asyncqueue.QueueTask(action);
    }
    private void asyncworker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
    {
    }

    private void asyncworker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        if (asyncqueue != null)
        {
            asyncworker.RunWorkerAsync();
        }
    }
}

public class BackgroundQueue
{
    private Task previousTask = Task.FromResult(true);
    private object key = new object();
    public Task QueueTask(Action action)
    {
        lock (key)
        {
            previousTask = previousTask.ContinueWith(t => action()
                , CancellationToken.None
                , TaskContinuationOptions.None
                , TaskScheduler.Default);
            return previousTask;
        }
    }
    public Task<T> QueueTask<T>(Func<T> work)
    {
        lock (key)
        {
            var task = previousTask.ContinueWith(t => work()
                , CancellationToken.None
                , TaskContinuationOptions.None
                , TaskScheduler.Default);
            previousTask = task;
            return task;
        }
    }
}}  

那么我应该使用“动作”还是有更好的方法来做我正在尝试的事情?

PS:老实说,我现在还不知道上面的内容。我所知道的是,当我运行我的程序并单击按钮时,一切都会锁定大约 30 秒。我试图阻止这种情况发生,但我不知道现在从哪里开始。我是否正确使用了上述任何代码?

编辑:发现当Something被添加到后台队列时,它会立即开始工作,所以我不需要后台工作人员。我将不得不了解有关任务的更多信息。

【问题讨论】:

  • 使用 TPL 数据流的ActionBlock

标签: c# multithreading task backgroundworker


【解决方案1】:

我最终使用了一种变通方法并摆脱了 BackgroundWorker。 没看懂Tasks or Actions,现在对语法了解多了,后台worker完全没用了。正确语法 queue = new BackgroundQueue(); queue.queuetask(() => {code to run};);

我没有意识到该方法在传递给 QueueTask() 的那一刻开始运行。
觉得这个问题很愚蠢

【讨论】:

    猜你喜欢
    • 2021-01-30
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    相关资源
    最近更新 更多