我知道它有3种方法.在我的程序中,我有一个发送消息的方法.这通常很晚,程序有时根本不响应按钮按下发送消息.有时它比我期望的晚5秒,程序冻结.我想使用a BackgroundWorker按预期发送消息,并允许程序始终正常运行.我有用于在按钮处理程序中发送消息的代码.现在我在哪里放这个等效的代码?我希望所有这些仍然可以通过按钮按下来处理.
这是合适的处理程序吗?
backgroundWorker1.RunWorkerAsync();
Run Code Online (Sandbox Code Playgroud)
并在:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {}
Run Code Online (Sandbox Code Playgroud)
我要把我的代码放在按钮处理程序中?而这之前:
carga.progressBar1.Minimum = 0;
carga.progressBar1.Maximum = 100;
Run Code Online (Sandbox Code Playgroud)
Carga是ProgressBar的另一种形式.如何在此方案中使用BackgroundWorker?
每当我刷新标签时,我都会收到此错误: 调用线程无法访问此对象,因为另一个线程拥有它.我试图调用,但它失败了.我正在使用WPF表格.
delegate void lostfocs(string st);
private void imgPayment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Thread t = new Thread(modi);
t.Start();
}
void modi()
{
try
{
label1.Content = "df";
}
catch
{
lostfocs ld = new lostfocs(up);
// ld.Invoke("df");
object obj=new object();
ld.Invoke("sdaf");
}
}
void up(string st)
{
label1.Content = st;
}
Run Code Online (Sandbox Code Playgroud) 为什么我不能在以下代码中创建CroppedBitmap?我有一个例外:
调用线程无法访问此对象,因为另一个线程拥有它.
如果我将代码更改为
CroppedBitmap cb = new CroppedBitmap(new WriteableBitmap(bf), new Int32Rect(1, 1, 5, 5));
Run Code Online (Sandbox Code Playgroud)
异常消失了吗?为什么?
代码1,例外情况cb.Freeze():
public MainWindow()
{
InitializeComponent();
ThreadPool.QueueUserWorkItem((o) =>
{
//load a large image file
var bf = BitmapFrame.Create(
new Uri("D:\\1172735642.jpg"),
BitmapCreateOptions.None,
BitmapCacheOption.None);
bf.Freeze();
Dispatcher.BeginInvoke(
new Action(() =>
{
CroppedBitmap cb = new CroppedBitmap(bf, new Int32Rect(1,1,5,5));
cb.Freeze();
//set Image's source to cb....
}),
DispatcherPriority.ApplicationIdle);
}
);
}
Run Code Online (Sandbox Code Playgroud)
代码2,有效:
ThreadPool.QueueUserWorkItem((o) =>
{
var bf = BitmapFrame.Create(
new Uri("D:\\1172740755.jpg"),
BitmapCreateOptions.None,
//BitmapCreateOptions.DelayCreation,
BitmapCacheOption.None);
bf.Freeze();
var wb = new …Run Code Online (Sandbox Code Playgroud) 我在进度条实时显示更新时遇到了一些麻烦.
这是我现在的代码
for (int i = 0; i < 100; i++)
{
progressbar1.Value = i;
Thread.Sleep(100);
}
Run Code Online (Sandbox Code Playgroud)
但由于某种原因,进度条在函数运行时显示为空,然后在函数完成运行之前没有任何内容.有人可以向我解释如何做到这一点?我是C#/ WPF的新手,所以我不能100%确定如何在不同的线程上实现Dispatcher(如其他一些帖子所示)来解决这个问题.
为了澄清,我的程序有一个按钮,按下时,从文本框中获取值,并使用API检索信息,并根据它创建标签.我希望在每行数据处理完毕后更新进度条.
这就是我现在所拥有的:
private async void search(object sender, RoutedEventArgs e)
{
var progress = new Progress<int>(value => progressbar1.Value = value);
await Task.Run(() =>
{
this.Dispatcher.Invoke((Action)(() =>
{
some pre-processing before the actual for loop occur
for (int i = 0; i < numberofRows; i++)
{
label creation + adding
((IProgress<int>)progress).Report(i);
}
}));
});
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
我刚刚注意到,当我ViewModel从后台工作线程更改我的(MVVM)中的绑定属性时,我没有得到任何异常,并且视图已正确更新.这是否意味着我可以安全地依赖于wpf数据绑定编组ViewModelUI线程中的所有更改?我想我已经读过一个应该确保(在ViewModel)INotifyPropertyChanged.PropertyChanged线程上触发的内容.这有什么改变在3.5或什么?
所以我在c#/ wpf中制作一个简单的破砖游戏.我正在使用计时器遇到一个问题,我觉得这可能是一个简单的修复,但这里发生了什么.每当t_Elapsed被触发时它会尝试调用Update(),但是当它像OMG我那样不在正确的线程中时所以我不能这样做先生.如何从正确的线程中调用Game中的方法?(是的,我知道代码是丑陋的,并且有很多神奇的数字,但我只是在没有付出太多努力的情况下把它搞砸了.是的,我没有编程游戏的经验)
public partial class Game : Grid
{
public bool running;
public Paddle p;
public Ball b;
Timer t;
public Game()
{
Width = 500;
Height = 400;
t = new Timer(20);
p = new Paddle();
b = new Ball();
for (int i = 15; i < 300; i += 15)
{
for (int j = 15; j < 455; j += 30)
{
Brick br = new Brick();
br.Margin = new Thickness(j, i, j + 30, i + …Run Code Online (Sandbox Code Playgroud) 我有这个应用程序在调用dispatcher.invoke进行任何控制时冻结.
当我在radiobutton,Grid,Image ..etc中调用Dispatcher时,应用程序会冻结,但不会出错.任何帮助请!!! 谢谢
我调用线程方法RunClient
private void RunClient()
{
TcpClient client;
// instantiate TcpClient for sending data to server
try
{
// Step 1: create TcpClient and connect to server
client = new TcpClient();
client.Connect(ip, 5001);
// Step 2: get NetworkStream associated with TcpClient
output = client.GetStream();
// create objects for writing and reading across stream
writer = new BinaryWriter(output);
reader = new BinaryReader(output);
string theReply = "";
do
{
try
{
// read the string sent to the server …Run Code Online (Sandbox Code Playgroud) 我需要将一些网格列附加到网格,该网格最初只包含几列.创建列是长期运行的,我正在尝试使用async/await,但我得到"调用线程无法访问此对象,因为不同的线程拥有它"异常,所以有人可以指导我正确的方法做这个.AddRange调用发生异常.提前致谢.
private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
List<GridViewColumn> cols = await NewGridColsAsync();
viewGridControl.Columns.AddRange(cols);
}
private async Task<List<GridViewColumn>> NewGridColsAsync()
{
List<GridViewColumn> cols = new List<GridViewColumn>();
await Task.Run(() =>
{
for (int i = 0; i < 100; i++)
{
cols.Add(new GridViewColumn());
}
});
return cols;
}
Run Code Online (Sandbox Code Playgroud) 有没有办法解决这个错误"调用线程无法访问此对象,因为不同的线程拥有它"而不使用调度程序,因为当代码有更长的处理时间时,调度程序会导致UI冻结是否有其他方法可以执行此操作?不会导致UI冻结
我知道有类似的问题,比如Here And Here,我看了他们一切,但他们似乎不适合我.
我有一个帖子:
private void Sample()
{
Thread t = new Thread(new ThreadStart(Sample_Thread));
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
Run Code Online (Sandbox Code Playgroud)
在Sample_Thread中,我之前调用过MessageBox哪个工作正常.
private void Sample_Thread()
{
try{ ... }
catch(Exception e)
{
MessageBox.Show("SampleText");
}
}
Run Code Online (Sandbox Code Playgroud)
现在我尝试调用ModernDialog而不是MessageBox,它给了我错误,'The calling thread cannot access this object because a different thread owns it.'
所以我将我的代码更改为:
private void Sample_Thread()
{
try{ ... }
catch(Exception e)
{
Dispatcher.CurrentDispatcher.Invoke(() =>
{
ModernDialog.ShowMessage("SampleText");
});
}
}
Run Code Online (Sandbox Code Playgroud)
但是这仍然有同样的错误,我应该如何解决这个问题呢?谢谢!
c# ×9
wpf ×8
.net ×2
async-await ×1
asynchronous ×1
data-binding ×1
dispatcher ×1
mvvm ×1
sockets ×1
wpf-controls ×1