首页 \ 问答 \ 无法使用简单的Action 委托来注册取消(Can not use a simple Action delegate to register cancellation)

无法使用简单的Action 委托来注册取消(Can not use a simple Action delegate to register cancellation)

根据我正在阅读的内容,我应该能够注册一个Action类型的委托来取消执行,但编译器给我和错误说明:'DisplayMessage'委托不能在当前上下文中使用。 我不知道我做错了什么。 这里是代码在该地区评论,我得到的错误...

我更新了代码,而Console.Writeline正常工作时,调用消息框方法给了我一个错误,说明无法从方法组转换为Action委托。 这里是更新后的代码:

编辑:我之后的最后一个功能是调用一个实际的方法,可能与Action的签名略有不同。 以下修改类型的作品,除了两次打印窗口。 我不明白为什么它会这样做,因为我正在复制代码中相关Console.WriteLine行的每一行。 我意识到我写的方法和Register方法接受的是Action之间的类型不匹配。 现在,我基本上试图弄清楚当方法签名相同时,我得到两个MessageBox,并且代码是相同的。

感谢大家的反馈。 以下代码以我想要的方式工作。 这是评论,我张贴它,以防其他人喜欢做类似的事情。

using System;
using System.Threading;
using System.Windows.Forms;

namespace CancellationSource
{
    internal delegate void DisplayMessage(string message);
    internal static class Program
    {
        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 50));
            //ThreadPool.QueueUserWorkItem(o => Count(CancellationToken.None, 50));
            Console.WriteLine("Press <enter> to cancel the operation.");
            Console.ReadLine();

            Action<Object>   messageTarget;
            messageTarget = Console.WriteLine;
            cts.Token.Register(Console.WriteLine, null, true);
            messageTarget = ShowWindowsMessage;
            messageTarget ("This should print in box");
//This code opens a 
//Message box only when the called thread operation is cancelled. This code calls two different methods
//of type Action<Object> when the spawned / requested thread is canceled. 
            //cts.Token.Register(messageTarget, null, true);
            cts.Cancel();
            Console.ReadLine();
        }
//Notice in order to get the method below to execute upon thread cancelation, I had to make sure its
//its signature is one of Action<Object>
        private static void ShowWindowsMessage(object value)
        {
            var message = (string)value;
            MessageBox.Show(message);
        }

        private static void Count(CancellationToken token, Int32 countTo) {
            for (int count = 0; count < countTo; count++)
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine("Count is cancelled");
                    break;
                }
                Console.WriteLine(count);
                Thread.Sleep(200);
            }
            Console.WriteLine("Count is done");
        }
    }

}

According to the content I am reading, I should be able to register a delegate of type Action to be executed upon cancelation, but the complier gives me and error stating: 'DisplayMessage' delegate can not be used in the current context. I can not tell what I am doing wrong. Here is the code commented in the area, which I get the error...

I updated the code, and while Console.Writeline works, calling a message box method gives me an error stating can not convert from method group to Action delegate. Here is the updated code:

edit: The last functionality I was after was to call an actual method, one that perhaps has slightly different signature from Action. The following modification kind of works, except it prints the Window twice. I do not get why it is doing that since I am copying every line from the relevant Console.WriteLine lines in my code. I realized that I had a type mismatch between the method I wrote and what Register method accepts which is Action. Now I am basically trying to figure out what I get two MessageBoxs when the method signatures are the same, and the code is the same.

Thank you for everyone's feedback. The following code works the way I wanted. It is commented, and I am posting it in case someone else likes to do something similar.

using System;
using System.Threading;
using System.Windows.Forms;

namespace CancellationSource
{
    internal delegate void DisplayMessage(string message);
    internal static class Program
    {
        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource();
            ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 50));
            //ThreadPool.QueueUserWorkItem(o => Count(CancellationToken.None, 50));
            Console.WriteLine("Press <enter> to cancel the operation.");
            Console.ReadLine();

            Action<Object>   messageTarget;
            messageTarget = Console.WriteLine;
            cts.Token.Register(Console.WriteLine, null, true);
            messageTarget = ShowWindowsMessage;
            messageTarget ("This should print in box");
//This code opens a 
//Message box only when the called thread operation is cancelled. This code calls two different methods
//of type Action<Object> when the spawned / requested thread is canceled. 
            //cts.Token.Register(messageTarget, null, true);
            cts.Cancel();
            Console.ReadLine();
        }
//Notice in order to get the method below to execute upon thread cancelation, I had to make sure its
//its signature is one of Action<Object>
        private static void ShowWindowsMessage(object value)
        {
            var message = (string)value;
            MessageBox.Show(message);
        }

        private static void Count(CancellationToken token, Int32 countTo) {
            for (int count = 0; count < countTo; count++)
            {
                if (token.IsCancellationRequested)
                {
                    Console.WriteLine("Count is cancelled");
                    break;
                }
                Console.WriteLine(count);
                Thread.Sleep(200);
            }
            Console.WriteLine("Count is done");
        }
    }

}

原文:https://stackoverflow.com/questions/40721590
更新时间:2022-03-08 12:03

最满意答案

为了节省一点点的内存/时间,你可以像这样修改@Ben Bolker的解决方案:

datlist <- lapply(csvnames,read.csv, colClasses=c("character", "NULL"))
rowseq <- seq_len( max(vapply(datlist,nrow, integer(1))) )
keylist <- lapply(datlist,function(x) { x[[1]][rowseq] ) })
names(keylist) <- paste(KEYTERMS,csvnames,sep="_")
#do.call(cbind,keylist)
do.call(data.frame,keylist)

...我只是改变了,只有第一列被读取,并且通过观察选择延伸到字符矢量焊盘之外的序列自动地用NA来简化NA填充。

如果你保持旧的填充方式,至少应该使用NA_character_而不是NA来避免不必要的强制。

我还通过数字而不是名称来索引KEYTERMS列(因为应该只有一个)。 我也将sapply改为sapply ,因为我更喜欢它:) - 它实际上也更快。

最后你说你想要一个data.frame 。 最后一行产生的不是矩阵。


To save a LITTLE memory/time you could modify the solution from @Ben Bolker like this:

datlist <- lapply(csvnames,read.csv, colClasses=c("character", "NULL"))
rowseq <- seq_len( max(vapply(datlist,nrow, integer(1))) )
keylist <- lapply(datlist,function(x) { x[[1]][rowseq] ) })
names(keylist) <- paste(KEYTERMS,csvnames,sep="_")
#do.call(cbind,keylist)
do.call(data.frame,keylist)

...I just changed so that only the first column is read, and simplified the NA padding by observing that selecting a sequence that extends outside a character vector pads with NA automatically...

If you kept the old way of padding, you should at least pad with NA_character_ instead of NA to avoid unnecessary coercion.

I also index the KEYTERMS column by number instead of name (since there should be only one). I also changed sapply to vapply because I like it better :) - it actually is faster too.

Finally you said you wanted a data.frame. The last line produces that instead of a matrix.

相关问答

更多

相关文章

更多

最新问答

更多
  • 如何使用自由职业者帐户登录我的php网站?(How can I login into my php website using freelancer account? [closed])
  • 如何打破按钮上的生命周期循环(How to break do-while loop on button)
  • C#使用EF访问MVC上的部分类的自定义属性(C# access custom attributes of a partial class on MVC with EF)
  • 如何获得facebook app的publish_stream权限?(How to get publish_stream permissions for facebook app?)
  • 如何并排放置两个元件?(How to position two elements side by side?)
  • 在MySQL和/或多列中使用多个表用于Rails应用程序(Using multiple tables in MySQL and/or multiple columns for a Rails application)
  • 如何隐藏谷歌地图上的登录按钮?(How to hide the Sign in button from Google maps?)
  • Mysql左连接旋转90°表(Mysql Left join rotate 90° table)
  • 带有ImageMagick和许多图像的GIF动画(GIF animation with ImageMagick and many images)
  • 电脑高中毕业学习去哪里培训
  • 电脑系统专业就业状况如何啊?
  • IEnumerable linq表达式(IEnumerable linq expressions)
  • 如何在Spring测试中连接依赖关系(How to wire dependencies in Spring tests)
  • Solr可以在没有Lucene的情况下运行吗?(Can Solr run without Lucene?)
  • 如何保证Task在当前线程上同步运行?(How to guarantee that a Task runs synchronously on the current thread?)
  • 在保持每列的类的同时向数据框添加行(Adding row to data frame while maintaining the class of each column)
  • 的?(The ? marks in emacs/haskell and ghc mode)
  • 一个线程可以调用SuspendThread传递自己的线程ID吗?(Can a thread call SuspendThread passing its own thread ID?)
  • 延迟socket.io响应,并“警告 - websocket连接无效”(Delayed socket.io response, and “warn - websocket connection invalid”)
  • 悬停时的图像转换(Image transition on hover)
  • IIS 7.5仅显示homecontroller(IIS 7.5 only shows homecontroller)
  • 没有JavaScript的复选框“关闭”值(Checkbox 'off' value without JavaScript)
  • java分布式框架有哪些
  • Python:填写表单并点击按钮确认[关闭](Python: fill out a form and confirm with a button click [closed])
  • PHP将文件链接到根文件目录(PHP Linking Files to Root File Directory)
  • 我如何删除ListView中的项目?(How I can remove a item in my ListView?)
  • 您是否必须为TFS(云)中的每个BUG创建一个TASK以跟踪时间?(Do you have to create a TASK for every BUG in TFS (Cloud) to track time?)
  • typoscript TMENU ATagParams小写(typoscript TMENU ATagParams lowercase)
  • 武陟会计培训类的学校哪个好点?
  • 从链接中删除文本修饰(Remove text decoration from links)