问候,我正在用C#开发一些应用程序.目前我正在处理线程,我有一个问题,我在脑海里.Invoke和BeginInvoke有什么区别?我读了一些帖子,我在这里找到了一些有用的信息:这里
但是,以下代码中的Invoke和BeginInvoke之间有什么区别:
private void ProcessRoutine()
{
for (int nValue = StartFrom; nValue <= EndTo; nValue++)
{
this.Invoke(this.MyDelegate, nValue);
//this.BeginInvoke(this.MyDelegate, nValue);
}
MessageBox.Show("Counting complete!");
}
private void MessageHandler(int progress)
{
lblStatus.Text = lblStatus.Text = "Processing item: " + progress.ToString();
progressBar1.Value = progress;
}
Run Code Online (Sandbox Code Playgroud)
其中MyDelegate是对MessageHandler函数的引用.
我注意到使用BeginInvoke lblStatus.Text没有刷新,使用Invoke刷新标签.另外我知道Invoke等待它的执行完成.我感兴趣的最重要的案例是为什么在这种情况下刷新标签文本会有所不同.
有关AsyncCallback和IAsyncResult的回调模式的两个问题.
我用代码示例更改了问题:
using System;
using System.Collections.Generic;
using System.Text;
namespace TestAsync
{
class Program
{
private static Wrapper test = new Wrapper();
static void Main(string[] args)
{
test.BeginMethod("parameter 1", "parameter 2", Callback);
Console.ReadKey();
}
private static void Callback(IAsyncResult ar)
{
string result = test.EndMethod(ar);
}
}
public interface ITest
{
IAsyncResult BeginMethod(string s1, string s2, AsyncCallback cb, object state);
string EndMethod(IAsyncResult result);
}
public class Wrapper
{
private ITest proxy = new Test();
public void BeginMethod(string s1, string s2, AsyncCallback cb) …Run Code Online (Sandbox Code Playgroud) 我需要知道Control.BeginInvoke和Control.Invoke调用是否会按照调用的顺序执行.
我有以下场景:
步骤1-4的执行顺序保证按所示顺序排列(从技术上讲,顺序不能保证是这样的,但我所拥有的问题仅在订单如图所示时才相关).
我的问题是,在步骤2中的BeginInvoke调用之前是否有可能执行步骤3中的Invoke/BeginInvoke调用?
另外,请不要评论阻止UI线程.
这是来自WinForms的旧代码:
private void ValueChanged(double inValue1, double inValue2) {
//only manual mode for this driver, so that's easy.
if (ValueLabel.InvokeRequired) {
ValueLabel.Invoke(new MethodInvoker(delegate {
ValueLabel.Text = (inValue1* inValue2/ 1000).ToString("f1");
}
));
}
else {
ValueLabel.Text = (inValue1* inValue2/ 1000).ToString("f1");
}
}
Run Code Online (Sandbox Code Playgroud)
是否有一种简单的方法将其转换为WPF友好?到目前为止,我有:
private void KVPValueChanged(double inValue1, double inValue2) {
if (ValueLabel.Dispatcher.Thread == Thread.CurrentThread){
ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
} else {
ValueLabel.Dispatcher.BeginInvoke(delegate {
ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
});
}
}
Run Code Online (Sandbox Code Playgroud)
但是第二个"代表"呼叫失败了.我该如何调用此委托?我想我可以完成整个制作委托方法,制作委托方法的实例,调用该特定实例等,但我认为这些匿名委托的重点是避免这种麻烦.另外,我的旧winforms代码在整个地方都有第一个实现,所以我真的想避免让我的所有代表去匿名化.
编辑:我可以像以前一样尝试使用MethodInvoker,但编译器会感到困惑.MethodInvoker是System.Windows.Forms的一部分,因此使用该方法不起作用.如:
private void ValueChanged(double inValue1, double inValue2) { …Run Code Online (Sandbox Code Playgroud) 在Silverlight 4中,我有一个自定义服务类,它有一个异步的Completed事件.在Completed事件中,我获取返回的数据并通过以下方式调用populate方法:
private void service_Completed(object sender, CompletedEventArgs args)
{
Dispatcher.BeginInvoke(() => populateInbox(args.Jobs));
}
private void populateInbox(List<JobViewModel> jobs)
{
inbox.DataContext = jobs;
}
Run Code Online (Sandbox Code Playgroud)
BeginInvokeSL4中的工作,但是当我将它移植到WPF时,我收到以下错误:
无法将lambda表达式转换为类型'System.Delegate',因为它不是委托类型
我尝试将其更改为一个内联的,匿名的,参数化的代表:
Dispatcher.BeginInvoke(delegate(List<JobViewModel> jobs)
{
inbox.DataContext = jobs;
});
Run Code Online (Sandbox Code Playgroud)
但是,这会产生相同的编译时错误.
知道如何在WPF中使用它吗?重构使用BackgroundWorker它不是我的选择.
我想从我的库类中引发一系列事件,但我担心一些事件订阅者会很粗鲁并且需要很长时间来处理一些事件,从而阻止了引发事件的线程.我以为我可以通过使用线程池线程来提升每个事件来保护提升线程:
if (packet != null && DataPacketReceived != null)
{
var args = new DataPacketEventArgs(packet);
DataPacketReceived.BeginInvoke(this, args, null, null);
}
Run Code Online (Sandbox Code Playgroud)
当事件只有一个订阅者时,这很好,但是一旦第二个订阅者到达,DataPacketReceived就会成为多播委托,并且我得到一个参数异常,并显示错误消息"委托必须只有一个目标".是否有一种简单的方法可以在单独的线程上引发事件,或者我是否必须启动一个线程然后从那里引发事件?
有人可以解决我遇到的问题吗?
我正在研究一个wpf项目.方案如下:
我需要在主UI线程上弹出一个窗口(模型窗口),然后关闭它.这些工作是从另一个UI线程开始的(阻止用户点击主UI窗口.)然后我关闭这个窗口.主要代码如下所示.它有效.
据我所知,close方法在ShowDialog()返回之前不会被执行(至少在UI线程上是这种情况,我的意思是没有调度程序的代码),有没有人有多线程的经验?
Window window;
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(() =>
{
//create a window and let user work from this thread
//code is omitted.
//create another window on main UI thread
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
window = new Window();
window.ShowDialog();
}));
//do some work here
Thread.Sleep(1000);
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
//Thread.Sleep(1000);
window.Close();
}));
});
thread.Start();
}
Run Code Online (Sandbox Code Playgroud)
感谢您的时间!
在网页上,我正在呼叫第三方,它不允许我以编程方式设置超时.我调用BeginInvoke并使用AsyncWaitHandle.WaitOne等待指定的时间.
如果呼叫超时,我继续前进,忘记我开始的线程呼叫.我的问题是,在超时情况下,我是否还要以某种方式调用EndInvoke?这个MSDN页面上的"注意"注释让我想知道我是否应该:http://msdn.microsoft.com/en-us/library/2e08f6yc(VS.71).aspx
如果您认为我应该,那么接下来的问题是,如果我的网页已经完成处理并在第三方回来之前返回到客户端,那么回调方法是否会在那里听取运行代码?一旦我的请求/响应完成,服务器是否停止寻找活动?
这是我正在使用的代码:
public class RemotePaymentProcessor
{
private delegate string SendProcessPaymentDelegate(string creditCardNumber);
private string SendProcessPayment(string creditCardNumber)
{
string response = string.Empty;
// call web service
SlowResponseService.SlowResponseService srs = new WebServiceTimeout.SlowResponseService.SlowResponseService();
response = srs.GetSlowResponse(creditCardNumber);
return response;
}
public string ProcessPayment(string creditCardNumber, int timeoutMilliseconds)
{
string response = string.Empty;
SendProcessPaymentDelegate sppd = new SendProcessPaymentDelegate(SendProcessPayment);
IAsyncResult ar = sppd.BeginInvoke(creditCardNumber, null, new object());
if (!ar.AsyncWaitHandle.WaitOne(timeoutMilliseconds, false))
{
// Async call did not return before timeout
response = "TIMEOUT";
}
else …Run Code Online (Sandbox Code Playgroud) 在我的WPF应用程序中,我想在非UI线程中做一些工作,以避免UI变得无响应.为此我做了这个:
var caller = new AsyncMethodCaller<Pattern>(this.SetPatternType);
caller.BeginInvoke(_patterns, null, null);
Run Code Online (Sandbox Code Playgroud)
代表被定义为,
public delegate void AsyncMethodCaller<in T>(IEnumerable<T> data);
Run Code Online (Sandbox Code Playgroud)
我的问题是:
是否BeginInvoke()创建一个新线程并在其中SetPatternType运行回调?如果是这样,这个帖子持续多久?
这种方法总的来说好吗?如果没有,它有什么问题?我可能面临哪些潜在的问题?
我正在使用C#4.0和Visual Studio 2010.
编辑:
我还需要一些关于这些的指导原则:
什么时候我应该自己创建一个新线程,何时应该使用BeginInvoke()?什么时候应该使用DispatcherObject.Dispatcher.BeginInvoke()对象?
根据Jon Skeet的说法,"您只能在具有单个目标调用的委托上调用BeginInvoke."
这是为什么?真正的原因是什么?
注意:为了澄清(因为我犯了这个错误),我说的BeginInvoke是代表,而不是控件.
begininvoke ×10
c# ×6
wpf ×4
.net ×3
delegates ×3
asynchronous ×2
invoke ×2
dispatcher ×1
events ×1
iasyncresult ×1
timeout ×1
winforms ×1